@acepad/keypad
v1.0.0
Published
NOTE: This package is supporsed to work in [AcePad](https://github.com/hoge1e3/acepad-dev), not a regular node envronment.
Downloads
48
Readme
NOTE: This package is supporsed to work in AcePad, not a regular node envronment.
@acepad/keypad
A virtual keypad library for the AcePad editor. Handles key rendering, modifier key state management, long-tap behavior, and key event dispatching.
Installation
This package is part of the @acepad monorepo. It is typically installed as a dependency rather than standalone.
Overview
@acepad/keypad provides the following modules:
| Module | Description |
|---|---|
| keypad.ts | Core keypad initialization, button rendering, and click handling |
| modifier.ts | Modifier key state (shift, ctrl, sym, etc.) management |
| longtap.ts | Long-tap / auto-repeat touch/mouse event handling |
| types.ts | Shared type definitions and constants |
Modifier Keys
The following modifier keys are supported:
| Key | Description |
|---|---|
| shift | Shift modifier (shows uppercase / alternate characters) |
| ctrl | Control modifier (triggers ctrl-prefixed commands) |
| edit | Edit mode modifier |
| sym | Symbol modifier (shows symbol layer on keys) |
| select | Selection mode (converts arrow keys to shift+arrow) |
Modifier keys support three states:
| Value | Meaning |
|---|---|
| 0 | Off |
| 1 | Active (single-shot — clears after next key press) |
| 2 | Locked (stays active until tapped again) |
Lock behavior is controlled by the lock data attribute on the button element:
| Lock Type | Behavior |
|---|---|
| "single" | Locks on first tap |
| "double" | Locks on double tap (default) |
| "none" | Never locks |
Button Data Attributes
Buttons inside #keypad can carry the following data-* attributes to define their behavior:
| Attribute | Type | Description |
|---|---|---|
| data-text | string | Character(s) to insert |
| data-key | string | Key name (e.g. ArrowLeft, Enter) |
| data-command | string | AcePad command string (sent as ace:<command>) |
| data-modifier | KP_ModifierKeys | Makes the button a modifier toggle |
| data-modifier-off | KP_ModifierKeys | Clears this modifier when pressed |
| data-lock | LockType | Lock behavior for modifier buttons |
| data-ctrl | string | Command triggered when ctrl modifier is active |
| data-keycode | string | Raw keycode (legacy use) |
Multi-character chr buttons
Buttons with the class chr support automatic layered text rendering:
- 1 alphabetic character → generates
no-shiftandshiftspans (lower/upper) - 2+ characters with an alphabetic first char → also generates
symspan - 2 characters, both non-alpha → generates
no-symandsymspans
API
initKeypad({ events })
Initializes the entire #keypad element. Scans all button elements, sets up tap handlers, adds modifier CSS rules, and runs layout justification.
import { initKeypad } from "@acepad/keypad";
initKeypad({ events: myEventHandler });eventsmust be anEventHandlerfrom@hoge1e3/events. The keypad fires:keyclick— when a key is pressed{ b: HTMLElement }renderModifierState— after the modifier state is re-rendered{}
initKey(button)
Initializes a single button element (called automatically by initKeypad).
doClick(button)
Programmatically triggers the action of a button as if it were tapped.
import { doClick } from "@acepad/keypad";
doClick(myButtonElement);doClickRender(button)
Same as doClick, but also fires the keyclick event and re-renders the modifier state.
getDatas(element)
Reads all data-* attributes from an element and its visible children, returning a Datas object.
import { getDatas } from "@acepad/keypad";
const d = getDatas(buttonEl);
// d.text, d.modifier, d.command, ...renderModifierState()
Applies CSS classes to #keypad reflecting the current modifier state. For each active modifier key k, adds class k and optionally lock-k to #keypad.
toggleSym()
Toggles the sym modifier to locked state (2), if a sym button is visible.
justify(row) / justifyAll()
Distributes visible child elements of a .justify row evenly by setting their widths as percentages. justifyAll applies this to all .justify elements and attaches a ResizeObserver.
hasSym()
Returns true if a visible [data-modifier="sym"] button exists in the DOM.
showGuide(button, size?)
Displays a floating guide overlay over the given button (or the button matching the given text), which shrinks over time. Useful for tutorials or onboarding.
textToButton()
Returns a map of { [text]: HTMLElement } for all buttons in #keypad that have a data-text value.
Modifier API (modifiers namespace)
Exported as modifiers from the main module:
import { modifiers } from "@acepad/keypad";| Function | Description |
|---|---|
| getModifier(key) | Returns current state value (0, 1) |
| setModifier(key, value) | Sets modifier to 0, 1, or 2 (locked) |
| modifierLocked(key) | Returns whether modifier is locked |
| clearUnlockedModifiers() | Clears all non-locked modifiers |
| modifierButtonPressed(datas) | Handles tap on a modifier button |
| modifierStateToKeyboardEvent(state?) | Converts modifier state to a { shiftKey, ctrlKey, ... } object |
| currentModifierState() | Returns the raw modifier state record |
| addModifierStyle() | Injects CSS rules for modifier visibility masking |
Long-tap Behavior (longtap module)
setLongtap(element, handlers) attaches touch/mouse event listeners to an element and supports:
start(e)— called on initial press; shows a visual tiplongtap(e)— called after 300ms holdautorepeat— iftrue, auto-repeats thestarthandler every 30ms after the initial long-tap delayend(e)— called on release; hides the tip
A tip element (#tip) must exist in the DOM for visual feedback.
CSS Classes
The keypad relies on the following CSS class conventions:
| Class | Applied to | Meaning |
|---|---|---|
| chr | button | Button text will be split into shift/sym layers |
| autorepeat | button | Button uses auto-repeat on long-tap |
| justify | container | Children will be auto-justified to fill the row |
| mask | span inside button | Toggled visible/hidden based on modifier state |
| no-shift / shift | span.mask | Shown when shift is off / on |
| no-sym / sym | span.mask | Shown when sym is off / on |
| {modifier} | #keypad | Added when that modifier is active |
| lock-{modifier} | #keypad | Added when that modifier is locked |
Dependencies
@hoge1e3/key-stream— key event push/sync pipeline@hoge1e3/events— event handler interfaceuser-gesture— gesture event handler setup@hoge1e3/on-resume— resume event for cleaning up tap state- jQuery (
$) — DOM manipulation (expected as a global)
License
MIT License.
