refactor (simplification): eliminate (CM-based)MiniEditor replaced with standard browser input

This commit is contained in:
Zef Hemel
2026-06-02 09:00:43 +02:00
parent 0a1e1354cd
commit 3ee2d4ef73
24 changed files with 376 additions and 430 deletions
+26 -1
View File
@@ -7,14 +7,39 @@ export type InputProps =
class?: string;
/** Ref to the underlying <input> (Preact function components don't forward `ref`). */
inputRef?: Ref<HTMLInputElement>;
/** Called with the current value when Enter is pressed in the field. */
onConfirm?: (value: string) => void;
/** Called with the current value when Escape is pressed in the field. */
onExit?: (value: string) => void;
};
export function Input({ class: extra, type, inputRef, ...rest }: InputProps) {
export function Input(
{ class: extra, type, inputRef, onConfirm, onExit, onKeyDown, ...rest }:
InputProps,
) {
return (
<input
ref={inputRef}
type={type ?? "text"}
class={cx("sb-input", extra)}
onKeyDown={onConfirm || onExit || onKeyDown
? (e) => {
// Run any caller-supplied handler first; it may call preventDefault().
onKeyDown?.(e);
// Ignore Enter/Escape that are part of an IME composition (e.g. CJK
// candidate confirmation), so they don't submit a half-composed value.
if (e.defaultPrevented || e.isComposing) {
return;
}
if (onConfirm && e.key === "Enter") {
e.preventDefault();
onConfirm(e.currentTarget.value);
} else if (onExit && e.key === "Escape") {
e.preventDefault();
onExit(e.currentTarget.value);
}
}
: undefined}
{...rest}
/>
);
+11
View File
@@ -30,6 +30,17 @@ test("Input renders sb-input with default type text", () => {
expect(html).toContain('type="text"');
});
test("Input renders cleanly when onConfirm/onExit are provided", () => {
const html = render(
h(Input, { value: "hi", onConfirm: () => {}, onExit: () => {} }),
);
expect(html).toContain('class="sb-input"');
expect(html).toContain('value="hi"');
// Callback props must not leak as DOM attributes
expect(html).not.toContain("onConfirm");
expect(html).not.toContain("onExit");
});
test("Select wraps options", () => {
const html = render(h(Select, {}, h("option", {}, "A")));
expect(html).toContain('class="sb-select"');