Move NumberInput.svelte input processing from JS to Rust (#4274)

* Move NumberInput.svelte input processing from JS to Rust

* Fix edge cases
This commit is contained in:
Keavon Chambers
2026-06-22 14:57:11 -07:00
committed by GitHub
parent f798b48b83
commit c1fa8ba8da
9 changed files with 77 additions and 45 deletions
@@ -215,10 +215,11 @@
component: NumberInput,
getProps: (props, index) => ({
...props,
incrementCallbackIncrease: () => widgetValueCommitAndUpdate(index, "Increment", false),
incrementCallbackDecrease: () => widgetValueCommitAndUpdate(index, "Decrement", false),
incrementCallbackIncrease: () => widgetValueCommitAndUpdate(index, { increment: "Increase" }, false),
incrementCallbackDecrease: () => widgetValueCommitAndUpdate(index, { increment: "Decrease" }, false),
$$events: {
value: (e: CustomEvent) => widgetValueUpdate(index, e.detail, true),
commitText: (e: CustomEvent) => widgetValueUpdate(index, e.detail, true),
startHistoryTransaction: () => widgetValueCommit(index, props.value),
commitHistoryTransaction: () => editor.endTransaction(),
},
@@ -4,7 +4,6 @@
import FieldInput from "/src/components/widgets/inputs/FieldInput.svelte";
import { PRESS_REPEAT_DELAY_MS, PRESS_REPEAT_INTERVAL_MS } from "/src/managers/input";
import { browserVersion } from "/src/utility-functions/platform";
import { evaluateMathExpression } from "/wrapper/pkg/graphite_wasm_wrapper";
import type { ActionShortcut, EditorWrapper, NumberInputIncrementBehavior, NumberInputMode } from "/wrapper/pkg/graphite_wasm_wrapper";
const BUTTONS_LEFT = 0b0000_0001;
@@ -12,7 +11,12 @@
const BUTTON_LEFT = 0;
const BUTTON_RIGHT = 2;
const dispatch = createEventDispatcher<{ value: number | undefined; startHistoryTransaction: undefined; commitHistoryTransaction: undefined }>();
const dispatch = createEventDispatcher<{
value: number | undefined;
commitText: string;
startHistoryTransaction: undefined;
commitHistoryTransaction: undefined;
}>();
const editor = getContext<EditorWrapper>("editor");
@@ -247,21 +251,11 @@
// The `unFocus()` call at the bottom of this function and in `onTextChangeCanceled()` causes this function to be run again, so this check skips a second run.
if (!editing) return;
// Insert a leading zero before all decimal points lacking a preceding digit, since the library doesn't realize that "point" means "zero point".
const textWithLeadingZeroes = text.replaceAll(/(?<=^|[^0-9])\./g, "0."); // Match any "." that is preceded by the start of the string (^) or a non-digit character ([^0-9])
// The backend evaluates the math, validates against this widget's constraints, and (only when changed) applies it within a history transaction before resending the widget.
dispatch("commitText", text);
let newValue = evaluateMathExpression(textWithLeadingZeroes);
if (newValue !== undefined && isNaN(newValue)) newValue = undefined; // Rejects `sqrt(-1)`
if (newValue !== undefined) {
const oldValue = value !== undefined && isInteger ? Math.round(value) : value;
if (newValue !== oldValue) {
dispatch("startHistoryTransaction");
transactionInProgress = true;
}
}
updateValue(newValue);
commitTransactionIfInProgress();
// Revert the field to the current value's canonical display; an accepted change resends the widget and re-runs `watchValue` to show the new value.
text = displayText(value, unit);
editing = false;
self?.unFocus();