@kkeyboard/react
v0.3.15
Published
One-command React Khmer smart input plus headless bindings for KKeyboard
Readme
@kkeyboard/react
This package provides a batteries-included React input plus a framework-neutral hook and compact suggestion UI. It does not depend on shadcn or any application design system.
Fastest integration
Install one package:
npm install @kkeyboard/reactThen use the ready-made input. It downloads the published Khmer runtime once, caches it in the browser, and reuses it on later visits (including offline visits when the browser cache is available):
import { useState } from "react";
import { KKeyboardInput } from "@kkeyboard/react";
import "@kkeyboard/react/styles.css";
export function KhmerInput() {
const [value, setValue] = useState("");
return (
<KKeyboardInput
value={value}
onChange={(event) => setValue(event.target.value)}
placeholder="វាយជាខ្មែរ ឬ khnom"
aria-label="Khmer text"
/>
);
}KKeyboardInput keeps normal Space as a normal visible space when the user
keeps their own spelling. Press Enter, Tab, a number key, or click a candidate
to accept a suggestion; accepted words use the invisible boundary needed for
Khmer word deletion. Current-word completion is enabled by default, while
next-word prediction is opt-in:
<KKeyboardInput
nextWordSuggestionsEnabled
mode="auto"
register="auto"
value={value}
onChange={(event) => setValue(event.target.value)}
/>For Next.js, place the component in a client component ("use client"). No
Tiptap package or network service is required for this ready-made textarea.
The first runtime load is local to the browser; the engine does not send typed
text to a server.
Custom engine or advanced hosts
Pass an engine to avoid loading the bundled runtime, or use the lower-level hook when integrating with Tiptap, a custom editor, or another design system.
import { useMemo } from "react";
import {
KKeyboardSuggestionPopover,
useKKeyboard,
} from "@kkeyboard/react";
import "@kkeyboard/react/styles.css";
import { createTiptapInputAdapter } from "@kkeyboard/tiptap";
const adapter = useMemo(
() => createTiptapInputAdapter(editor),
[editor],
);
const keyboard = useKKeyboard({ engine, adapter });
return (
<KKeyboardSuggestionPopover
view={keyboard.view}
onSelect={(item) => (
keyboard.view.query
? keyboard.commitCandidate(item)
: keyboard.commitNextWord(item.text)
)}
/>
);import { useMemo } from "react";
import {
KKeyboardSuggestionPopover,
useKKeyboard,
} from "@kkeyboard/react";
import "@kkeyboard/react/styles.css";
import { createTiptapInputAdapter } from "@kkeyboard/tiptap";
const adapter = useMemo(
() => createTiptapInputAdapter(editor),
[editor],
);
const keyboard = useKKeyboard({ engine, adapter });
return (
<KKeyboardSuggestionPopover
view={keyboard.view}
onSelect={(item) => (
keyboard.view.query
? keyboard.commitCandidate(item)
: keyboard.commitNextWord(item.text)
)}
/>
);The hook manages controller creation, editor event subscription, keyboard cleanup, and suggestion state. The host remains responsible for positioning the popover beside the editor caret.
Next-word prediction is disabled unless the host explicitly enables it through
nextWordSuggestionsEnabled or getInputSettings.
