npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@tdh-keyboard/core

v1.0.10

Published

中文虚拟键盘组件库核心包

Readme

@tdh-keyboard/core

@tdh-keyboard/core 是中文虚拟键盘组件库的底层能力包,提供全局配置、输入框写入、键盘定位、长按连发、手写画布,以及拼音引擎和手写识别器的通用接口。

它本身不包含 UI,更适合以下场景:

  • @tdh-keyboard/vue@tdh-keyboard/react@tdh-keyboard/native 提供底层能力
  • 在你自己的组件中复用输入框写入和长按逻辑
  • 接入自定义拼音引擎或手写识别服务

安装

npm install @tdh-keyboard/core

导出总览

| 导出 | 类型 | 作用 | | --- | --- | --- | | setKeyboardConfig | function | 设置全局键盘默认配置 | | getKeyboardConfig | function | 读取当前全局键盘配置 | | registerPinyinEngine | function | 注册全局拼音引擎实例 | | getPinyinEngine | function | 获取已注册的拼音引擎 | | registerHandwritingRecognizer | function | 注册全局手写识别器实例 | | getHandwritingRecognizer | function | 获取已注册的手写识别器 | | isInputElement | function | 判断元素是否为可写入的输入框 | | getInputElement | function | 获取当前激活的输入框 | | writeToInputElement | function | 在输入框光标位置写入文本 | | enterToInputElement | function | 向 textarea 插入换行 | | delToInputElement | function | 删除输入框选区或光标前字符 | | clearToInputElement | function | 清空输入框内容并将光标移到开头 | | moveCursor | function | 移动输入框光标 | | observePositionTarget | function | 监听浮动定位目标的位置变化 | | calculateKeyboardPosition | function | 计算键盘浮动/底部定位坐标 | | createKeyRepeater | function | 创建长按连发控制器 | | hasVisibleToolbarTrailingActions | function | 判断工具栏右侧是否还有可见一级动作 | | shouldShowToolbarDivider | function | 判断工具栏分割线是否应该显示 | | CanvasDrawer | class | 管理手写画布、笔迹和自动清屏 | | KeyboardConfig | interface | 键盘全局配置类型 | | ToolbarActionVisibilityOptions | interface | 工具栏动作显隐配置类型 | | PinyinEngine | interface | 拼音引擎通用接口 | | PinyinState | interface | 拼音候选状态类型 | | Candidate | interface | 拼音候选项类型 | | HandwritingRecognizer | interface | 手写识别器通用接口 | | RecognizerInitOptions | interface | 手写识别初始化参数 | | TextInputElement | type | 文本输入元素类型别名 | | KeyboardPosition | interface | 键盘定位结果类型 | | KeyRepeatOptions | interface | 长按连发参数类型 | | KeyRepeater | interface | 长按连发实例类型 | | CanvasDrawerOptions | interface | 手写画布配置类型 |

快速示例

import {
  createKeyRepeater,
  delToInputElement,
  setKeyboardConfig,
  writeToInputElement,
} from '@tdh-keyboard/core'

setKeyboardConfig({
  defaultMode: 'zh',
  position: 'bottom',
  width: '100%',
  height: 'auto',
})

const input = document.querySelector('input')
const repeater = createKeyRepeater({
  delay: 400,
  interval: 60,
})

if (input) {
  writeToInputElement(input, '你')
}

const backspaceButton = document.querySelector('#backspace')

backspaceButton?.addEventListener('mousedown', () => {
  if (input) {
    repeater.start(() => delToInputElement(input))
  }
})

backspaceButton?.addEventListener('mouseup', () => {
  repeater.stop()
})

API 说明

配置与服务注册

setKeyboardConfig(config)

function setKeyboardConfig(config: KeyboardConfig): void

设置全局键盘配置。会与当前配置合并,而不是整体覆盖。

常用配置项:

  • defaultMode:默认键盘模式,可选 'en' | 'zh' | 'hand' | 'num' | 'num_pure' | 'id_card' | 'num_en_cap' | 'symbol'
  • enableHandwriting:是否启用手写模式
  • position:键盘定位方式,可选 'static' | 'float' | 'bottom'
  • floatMarginTop:浮动模式下键盘与输入框的垂直间距
  • floatPlacement:浮动模式下的渲染方向
  • disableWhenNoFocus:没有聚焦输入框时是否禁用键盘
  • manual:是否改为手动打开模式
  • numKeys:数字键盘的行布局
  • width:键盘宽度,支持 number | string,传 number 时按 px 处理
  • height:键盘高度,支持 number | string,传 number 时按 px 处理
  • wasmDir:默认拼音引擎使用的 RIME 资源目录

getKeyboardConfig()

function getKeyboardConfig(): KeyboardConfig

读取当前全局键盘配置。

registerPinyinEngine(engine)

function registerPinyinEngine(engine: PinyinEngine): void

注册全局拼音引擎实例。

getPinyinEngine()

function getPinyinEngine(): PinyinEngine | null

获取当前已注册的拼音引擎。

registerHandwritingRecognizer(recognizer)

function registerHandwritingRecognizer(recognizer: HandwritingRecognizer): void

注册全局手写识别器实例。

getHandwritingRecognizer()

function getHandwritingRecognizer(): HandwritingRecognizer | null

获取当前已注册的手写识别器。

输入框操作

isInputElement(el)

function isInputElement(el?: Element | null): el is TextInputElement

判断一个 DOM 元素是否为可写入的文本输入元素。

getInputElement()

function getInputElement(): TextInputElement

获取当前页面上正在聚焦的输入框。若当前没有激活的可输入元素,会抛出异常。

writeToInputElement(inputElement, text)

function writeToInputElement(inputElement: TextInputElement, text: string): void

向输入框当前光标位置写入文本。

enterToInputElement(inputElement)

function enterToInputElement(inputElement: TextInputElement): boolean

textarea 插入换行。

  • 如果目标是 textarea,会插入 \n 并返回 true
  • 如果目标不是 textarea,不会写入并返回 false

delToInputElement(inputElement)

function delToInputElement(inputElement: TextInputElement): void

删除输入框中的内容。优先删除选区,没有选区时删除光标前一个字符。

clearToInputElement(inputElement)

function clearToInputElement(inputElement: TextInputElement): void

清空输入框全部内容,并将光标移动到开头位置。如果输入框原本就是空字符串,则不会重复触发 input 事件。

moveCursor(inputElement, index)

function moveCursor(inputElement: TextInputElement, index: number): void

移动输入框光标到指定位置。

键盘定位

observePositionTarget(inputElement, onChange)

function observePositionTarget(
  inputElement: HTMLElement | null,
  onChange: () => void,
): () => void

监听输入框位置变化,适合浮动键盘在 scrollresize、视口变化时实时更新位置。

  • 返回值:清理函数
  • 适用场景:position === 'float' 时监听目标输入框位置

calculateKeyboardPosition(inputElement, keyboardElement, positionMode, floatMarginTop?, floatPlacement?, previousPlacement?)

function calculateKeyboardPosition(
  inputElement: HTMLElement | null,
  keyboardElement: HTMLElement | null,
  positionMode: 'static' | 'float' | 'bottom',
  floatMarginTop?: number,
  floatPlacement?: 'auto' | 'top' | 'right' | 'bottom' | 'left',
  previousPlacement?: 'top' | 'right' | 'bottom' | 'left',
): KeyboardPosition | null

根据定位模式计算键盘 DOM 的位置。

  • static:不计算位置,返回 null
  • bottom:固定在窗口底部
  • float:根据输入框位置浮动显示,并限制在视口范围内
  • 返回值中的 placement 用于表明最终采用的浮动方向

长按连发

createKeyRepeater(options?)

function createKeyRepeater(options?: KeyRepeatOptions): KeyRepeater

创建一个“长按后连续触发”的工具:

  • start(action):立即执行一次 action,随后按 delayinterval 连发
  • stop():停止重复执行

工具栏可见性

hasVisibleToolbarTrailingActions(options?)

function hasVisibleToolbarTrailingActions(options?: {
  showEnterAction?: boolean
  showClearAction?: boolean
  showCollapseAction?: boolean
}): boolean

判断工具栏右侧是否至少还有一个可见的一级动作。适合在你自定义工具栏时复用“右侧是否为空”的判断逻辑。

shouldShowToolbarDivider(options?)

function shouldShowToolbarDivider(options?: ToolbarActionVisibilityOptions): boolean

判断工具栏中间分割线是否应该显示。只有左侧和右侧都至少存在一个可见一级动作时才会返回 true

ToolbarActionVisibilityOptions

interface ToolbarActionVisibilityOptions {
  showModeSwitch?: boolean
  showEnterAction?: boolean
  showClearAction?: boolean
  showCollapseAction?: boolean
}

用于描述工具栏左侧切换按钮以及右侧一级动作的显隐状态。

手写画布

new CanvasDrawer(canvas, options?)

new CanvasDrawer(canvas: HTMLCanvasElement, options?: CanvasDrawerOptions)

创建一个手写画布控制器。

可选参数:

  • onDrawEnd:每次一笔书写结束后的回调
  • clearDelay:停止书写后自动清空的延迟,默认 1000ms

常用实例方法:

canvasDrawer.clearCanvas()

canvasDrawer.clearCanvas(): void

清空画布并重绘辅助网格,同时清空当前笔迹数据。

canvasDrawer.getStrokeData()

canvasDrawer.getStrokeData(): ReadonlyArray<number>

获取当前笔迹数据,格式为 [x1, y1, c1, x2, y2, c2, ...]

canvasDrawer.startClearTimer()

canvasDrawer.startClearTimer(): void

启动自动清空计时器。

canvasDrawer.resetClearTimer()

canvasDrawer.resetClearTimer(): void

取消当前自动清空计时器。

canvasDrawer.destroy()

canvasDrawer.destroy(): void

移除已绑定的鼠标和触摸事件,并清理定时器。

canvasDrawer.getCanvas()

canvasDrawer.getCanvas(): HTMLCanvasElement

返回内部持有的 canvas 元素。

canvasDrawer.getContext()

canvasDrawer.getContext(): CanvasRenderingContext2D

返回内部持有的 2D 绘图上下文。

类型

KeyboardConfig

全局键盘配置类型。

PinyinEngine

拼音引擎通用接口,要求实现:

  • initialize()
  • processInput(pinyin)
  • pickCandidate(index)
  • clearInput()
  • destroy()
  • 可选 setSimplified(simplified)

PinyinState

拼音候选状态类型,包含预编辑文本、候选列表、分页信息等字段。

Candidate

拼音候选项类型:

interface Candidate {
  text: string
  comment: string
}

HandwritingRecognizer

手写识别器通用接口,要求实现:

  • initialize(options?)
  • recognize(strokeData)
  • close()

RecognizerInitOptions

手写识别初始化参数,目前支持:

  • onProgress(progress):初始化进度回调