Fix FieldInput and several other Svelte bugs

This commit is contained in:
Keavon Chambers
2023-03-08 01:35:22 -08:00
parent 2e3495aa0e
commit 7ce9d6db05
9 changed files with 56 additions and 25 deletions
@@ -320,7 +320,10 @@
{/if}
<NumberInput
value={strength}
on:value={({ detail }) => setColorRGB(channel, detail)}
on:value={({ detail }) => {
strength = detail;
setColorRGB(channel, detail);
}}
min={0}
max={255}
minWidth={56}
@@ -341,7 +344,10 @@
{/if}
<NumberInput
value={strength}
on:value={({ detail }) => setColorHSV(channel, detail)}
on:value={({ detail }) => {
strength = detail;
setColorHSV(channel, detail);
}}
min={0}
max={channel === "h" ? 360 : 100}
unit={channel === "h" ? "°" : "%"}
@@ -358,7 +364,10 @@
<NumberInput
label="Alpha"
value={!isNone ? alpha * 100 : undefined}
on:value={({ detail }) => setColorAlphaPercent(detail)}
on:value={({ detail }) => {
if (detail !== undefined) alpha = detail / 100;
setColorAlphaPercent(detail);
}}
min={0}
max={100}
rangeMin={0}
@@ -59,7 +59,7 @@
return sparse;
}
function buildNodeCategories(nodeTypes: FrontendNodeType[], searchTerm: string) {
function buildNodeCategories(nodeTypes: FrontendNodeType[], searchTerm: string): [string, FrontendNodeType[]][] {
const categories = new Map();
nodeTypes.forEach((node) => {
if (searchTerm.length > 0 && !node.name.toLowerCase().includes(searchTerm.toLowerCase()) && !node.category.toLowerCase().includes(searchTerm.toLowerCase())) {
@@ -488,10 +488,10 @@
{#if nodeListLocation}
<LayoutCol class="node-list" data-node-list styles={{ "margin-left": `${nodeListX}px`, "margin-top": `${nodeListY}px` }}>
<TextInput placeholder="Search Nodes..." value={searchTerm} on:value={({ detail }) => (searchTerm = detail)} bind:this={nodeSearchInput} />
{#each nodeCategories as nodeCategory (nodeCategory[0])}
{#each nodeCategories as nodeCategory}
<LayoutCol>
<TextLabel>{nodeCategory[0]}</TextLabel>
{#each nodeCategory[1] as nodeType (String(nodeType))}
{#each nodeCategory[1] as nodeType}
<TextButton label={nodeType.name} action={() => createNode(nodeType.name)} />
{/each}
</LayoutCol>
@@ -121,7 +121,7 @@
{#if numberInput}
<NumberInput
{...exclude(numberInput)}
on:value={({ detail }) => debouncer(() => updateLayout(index, detail))}
on:value={({ detail }) => debouncer((value) => updateLayout(index, value)).updateValue(detail)}
incrementCallbackIncrease={() => updateLayout(index, "Increment")}
incrementCallbackDecrease={() => updateLayout(index, "Decrement")}
sharpRightCorners={nextIsSuffix}
@@ -31,8 +31,8 @@
let inputOrTextarea: HTMLInputElement | HTMLTextAreaElement;
let id = `${Math.random()}`.substring(2);
let macKeyboardLayout = platformIsMac();
let inputValue = value;
$: inputValue = value;
$: dispatch("value", inputValue);
// Select (highlight) all the text. For technical reasons, it is necessary to pass the current text.
@@ -52,7 +52,7 @@
export let incrementCallbackDecrease: (() => void) | undefined = undefined;
let self: FieldInput;
let text = displayText(value);
let text = displayText(value, displayDecimalPlaces, unit);
let editing = false;
// Stays in sync with a binding to the actual input range slider element.
let rangeSliderValue = value !== undefined ? value : 0;
@@ -84,10 +84,10 @@
if (typeof min === "number") sanitized = Math.max(sanitized, min);
if (typeof max === "number") sanitized = Math.min(sanitized, max);
text = displayText(sanitized);
text = displayText(sanitized, displayDecimalPlaces, unit);
}
function sliderInput() {
function onSliderInput() {
// Keep only 4 digits after the decimal point
const ROUNDING_EXPONENT = 4;
const ROUNDING_MAGNITUDE = 10 ** ROUNDING_EXPONENT;
@@ -113,10 +113,10 @@
// If we're in a dragging state, we want to use the new slider value
rangeSliderValueAsRendered = roundedValue;
updateValue(roundedValue);
updateValue(roundedValue, min, max, displayDecimalPlaces, unit);
}
function sliderPointerDown() {
function onSliderPointerDown() {
// We want to render the fake slider thumb at the old position, which is still the number held by `value`
rangeSliderValueAsRendered = value || 0;
@@ -124,7 +124,7 @@
// invocation will transition the state machine to `mousedown`. That's why we don't do it here.
}
function sliderPointerUp() {
function onSliderPointerUp() {
// User clicked but didn't drag, so we focus the text input element
if (rangeSliderClickDragState === "mousedown") {
const inputElement = self.element().querySelector("[data-input-element]") as HTMLInputElement | undefined;
@@ -160,7 +160,7 @@
const parsed = parseFloat(text);
const newValue = Number.isNaN(parsed) ? undefined : parsed;
updateValue(newValue);
updateValue(newValue, min, max, displayDecimalPlaces, unit);
editing = false;
@@ -168,7 +168,7 @@
}
function onCancelTextChange() {
updateValue(undefined);
updateValue(undefined, min, max, displayDecimalPlaces, unit);
editing = false;
@@ -181,11 +181,11 @@
const actions: Record<NumberInputIncrementBehavior, () => void> = {
Add: () => {
const directionAddend = direction === "Increase" ? step : -step;
updateValue(value !== undefined ? value + directionAddend : undefined);
updateValue(value !== undefined ? value + directionAddend : undefined, min, max, displayDecimalPlaces, unit);
},
Multiply: () => {
const directionMultiplier = direction === "Increase" ? step : 1 / step;
updateValue(value !== undefined ? value * directionMultiplier : undefined);
updateValue(value !== undefined ? value * directionMultiplier : undefined, min, max, displayDecimalPlaces, unit);
},
Callback: () => {
if (direction === "Increase") incrementCallbackIncrease?.();
@@ -197,20 +197,20 @@
action();
}
function updateValue(newValue: number | undefined) {
function updateValue(newValue: number | undefined, min: number | undefined, max: number | undefined, displayDecimalPlaces: number, unit: string) {
// Check if the new value is valid, otherwise we use the old value (rounded if it's an integer)
const nowValid = value !== undefined && isInteger ? Math.round(value) : value;
let cleaned = newValue !== undefined ? newValue : nowValid;
if (typeof min === "number" && !Number.isNaN(min) && cleaned !== undefined) cleaned = Math.max(cleaned, min);
if (typeof max === "number" && !Number.isNaN(max) && cleaned !== undefined) cleaned = Math.min(cleaned, max);
// Required as the call to update:value can, not change the value
text = displayText(value);
text = displayText(cleaned, displayDecimalPlaces, unit);
if (newValue !== undefined) dispatch("value", cleaned);
}
function displayText(value: number | undefined): string {
function displayText(value: number | undefined, displayDecimalPlaces: number, unit: string): string {
if (value === undefined) return "-";
// Find the amount of digits on the left side of the decimal
@@ -261,9 +261,9 @@
max={rangeMax}
step={sliderStepValue}
{disabled}
on:input={sliderInput}
on:pointerdown={sliderPointerDown}
on:pointerup={sliderPointerUp}
on:input={onSliderInput}
on:pointerdown={onSliderPointerDown}
on:pointerup={onSliderPointerUp}
tabindex="-1"
/>
{/if}