3 Commits

Author SHA1 Message Date
de1f9d6ab6 feat(ui): change inputnumber to snap to values when alt is pressed
Some checks failed
🚀 Lint & Test & Deploy / release (push) Has been cancelled
2026-02-06 15:44:24 +01:00
6acce72fb8 fix(ui): correctly initialize InputNumber
When the value is outside min/max the value should not be clamped.
2026-02-06 15:25:18 +01:00
cf8943b205 chore: pnpm update 2026-02-06 15:18:32 +01:00
8 changed files with 522 additions and 758 deletions

View File

@@ -18,7 +18,7 @@
"dependencies": {
"@nodarium/ui": "workspace:*",
"@nodarium/utils": "workspace:*",
"@sveltejs/kit": "^2.50.0",
"@sveltejs/kit": "^2.50.2",
"@tailwindcss/vite": "^4.1.18",
"@threlte/core": "8.3.1",
"@threlte/extras": "9.7.1",
@@ -34,11 +34,11 @@
"@eslint/js": "^9.39.2",
"@iconify-json/tabler": "^1.2.26",
"@iconify/tailwind4": "^1.2.1",
"@nodarium/types": "workspace:",
"@nodarium/types": "workspace:^",
"@playwright/test": "^1.58.1",
"@sveltejs/adapter-static": "^3.0.10",
"@sveltejs/vite-plugin-svelte": "^6.2.4",
"@tsconfig/svelte": "^5.0.6",
"@tsconfig/svelte": "^5.0.7",
"@types/file-saver": "^2.0.7",
"@types/three": "^0.182.0",
"@vitest/browser-playwright": "^4.0.18",
@@ -46,8 +46,8 @@
"eslint": "^9.39.2",
"eslint-plugin-svelte": "^3.14.0",
"globals": "^17.3.0",
"svelte": "^5.46.4",
"svelte-check": "^4.3.5",
"svelte": "^5.49.2",
"svelte-check": "^4.3.6",
"tslib": "^2.8.1",
"typescript": "^5.9.3",
"typescript-eslint": "^8.54.0",
@@ -55,7 +55,7 @@
"vite-plugin-comlink": "^5.3.0",
"vite-plugin-glsl": "^1.5.5",
"vite-plugin-wasm": "^3.5.0",
"vitest": "^4.0.17",
"vitest": "^4.0.18",
"vitest-browser-svelte": "^2.0.2"
}
}

View File

@@ -17,7 +17,7 @@
"author": "",
"license": "ISC",
"dependencies": {
"zod": "^4.3.5"
"zod": "^4.3.6"
},
"devDependencies": {
"dprint": "^0.51.1"

View File

@@ -33,25 +33,25 @@
"@eslint/compat": "^2.0.2",
"@eslint/eslintrc": "^3.3.3",
"@eslint/js": "^9.39.2",
"@nodarium/types": "workspace:",
"@nodarium/types": "workspace:^",
"@playwright/test": "^1.58.1",
"@sveltejs/adapter-static": "^3.0.10",
"@sveltejs/kit": "^2.50.0",
"@sveltejs/kit": "^2.50.2",
"@sveltejs/package": "^2.5.7",
"@sveltejs/vite-plugin-svelte": "^6.2.4",
"@testing-library/svelte": "^5.3.1",
"@types/eslint": "^9.6.1",
"@types/three": "^0.182.0",
"@typescript-eslint/eslint-plugin": "^8.53.0",
"@typescript-eslint/parser": "^8.53.0",
"@typescript-eslint/eslint-plugin": "^8.54.0",
"@typescript-eslint/parser": "^8.54.0",
"@vitest/browser-playwright": "^4.0.18",
"dprint": "^0.51.1",
"eslint": "^9.39.2",
"eslint-plugin-svelte": "^3.14.0",
"globals": "^17.3.0",
"publint": "^0.3.16",
"svelte": "^5.46.4",
"svelte-check": "^4.3.5",
"publint": "^0.3.17",
"svelte": "^5.49.2",
"svelte-check": "^4.3.6",
"svelte-eslint-parser": "^1.4.1",
"tslib": "^2.8.1",
"typescript": "^5.9.3",

View File

@@ -19,7 +19,6 @@
// normalize bounds
if (min > max) [min, max] = [max, min];
if (value > max) max = value;
let inputEl: HTMLInputElement | undefined = $state();
@@ -27,11 +26,18 @@
return Math.min(max, Math.max(min, v));
}
function snap(v: number) {
if (step) v = Math.round(v / step) * step;
function snap(v: number, s = step) {
if (s) v = Math.round(v / s) * s;
return +v.toFixed(3);
}
function getAutoStep(v: number): number {
const abs = Math.abs(v);
if (abs === 0) return 0.1; // fallback for 0
const exponent = Math.floor(Math.log10(abs));
return Math.pow(10, exponent);
}
let dragging = $state(false);
let startValue = 0;
let rect: DOMRect;
@@ -59,7 +65,8 @@
value = snap(
e.ctrlKey
? startValue + delta
: clamp(startValue + delta)
: clamp(startValue + delta),
(e.altKey && !step) ? getAutoStep(value) : step
);
}
@@ -105,7 +112,7 @@
}
onMount(() => {
value = snap(clamp(value));
value = snap(value);
});
</script>
@@ -130,7 +137,7 @@
<div
class="absolute inset-y-0 left-0 bg-layer-3 opacity-30 pointer-events-none transition-[width]"
class:transition-none={dragging}
style={`width: ${Math.min((value - min) / (max - min), 1) * 100}%`}
style={`width: ${Math.max(0, Math.min((value - min) / (max - min), 1) * 100)}%`}
>
</div>

View File

@@ -42,4 +42,18 @@ describe('InputNumber', () => {
await expect.element(input).toHaveAttribute('min', '0');
await expect.element(input).toHaveAttribute('max', '10');
});
it('should not clamp value on init when value exceeds min/max', async () => {
render(InputNumber, { value: 100, min: 0, max: 10 });
const input = page.getByRole('spinbutton');
await expect.element(input).toHaveValue(100);
});
it('should not clamp value on init when value is below min', async () => {
render(InputNumber, { value: -50, min: 0, max: 10 });
const input = page.getByRole('spinbutton');
await expect.element(input).toHaveValue(-50);
});
});

View File

@@ -12,11 +12,11 @@
"author": "",
"license": "ISC",
"dependencies": {
"@nodarium/types": "workspace:"
"@nodarium/types": "workspace:^"
},
"devDependencies": {
"dprint": "^0.51.1",
"vite": "^7.3.1",
"vitest": "^4.0.17"
"vitest": "^4.0.18"
}
}

1211
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -2,8 +2,8 @@ packages:
- app
- packages/*
- nodes/**
- "!**/.template/**"
- "!**/pkg/**"
- '!**/.template/**'
- '!**/pkg/**'
catalog:
chokidar-cli: github:open-cli-tools/chokidar-cli#semver:v4.0.0