feat(ui): render the generated style parameter rows through Vue

This commit is contained in:
Sameh Khamis committed 2026-10-30 23:23:58 -07:00
1 parent 926253e8a3
commit bca7495cbf
9 files changed
+223 -202

No files matched your search

+2 -106
View File
@@ -1,9 +1,7 @@
import assert from 'node:assert/strict';
import test from 'node:test';
import {
bindApplicationShortcuts,
createStyleParameters,
} from './visualInput.js';
// Generated parameter rows render through Vue: styleParameters.test.mjs.
import { bindApplicationShortcuts } from './visualInput.js';
class Element {
constructor(tagName = 'DIV', ownerDocument) {
@@ -141,105 +139,3 @@ test('destroy synchronously removes shortcuts and a replacement binds once', ()
assert.deepEqual(f.calls, ['new']);
replacement.destroy();
});
function parameters() {
const documentRef = {
createElement: (tag) => new Element(tag.toUpperCase(), documentRef),
};
const container = new Element('DIV', documentRef);
const controller = createStyleParameters({ container });
const values = { amount: 0.25, scale: 2 };
const uniforms = {
amount: { label: '<Amount>', min: 0, max: 1 },
scale: { label: 'Scale', min: 0, max: 10 },
};
const order = [];
const options = {
uniforms,
readValue: (name) => values[name],
writeValue: (name, value) => {
order.push(['write', name, value]);
values[name] = value;
},
onChange: () => {
order.push(['change', container.children[0]?.children[2].textContent]);
},
};
controller.render(options);
return { container, controller, values, options, order };
}
test('parameter rows preserve labels, bounds, precision and initial values', () => {
const f = parameters();
assert.equal(f.container.children.length, 2);
const [label, slider, value] = f.container.children[0].children;
assert.equal(label.textContent, '<Amount>');
assert.equal(slider.attributes.get('aria-label'), '<Amount>');
assert.equal(slider.type, 'range');
assert.equal(slider.className, 'gev-quantitative-slider param-slider');
assert.equal(slider.min, 0);
assert.equal(slider.max, 1);
assert.equal(slider.step, '0.01');
assert.equal(value.textContent, '0.25');
assert.equal(f.container.children[1].children[1].step, '0.1');
assert.equal(f.container.children[1].children[2].textContent, '2.0');
assert.deepEqual(
f.order,
[],
'rendering must not write shader values or publish changes',
);
});
test('input writes numeric values, updates the readout, then requests a change', () => {
const f = parameters();
const slider = f.container.children[0].children[1];
slider.value = '0.75';
slider.emit('input');
assert.equal(f.values.amount, 0.75);
assert.deepEqual(f.order, [
['write', 'amount', 0.75],
['change', '0.75'],
]);
});
test('rebuilding the parameter panel revokes detached slider listeners', () => {
const f = parameters();
const oldSlider = f.container.children[0].children[1];
f.controller.render({
...f.options,
uniforms: { scale: f.options.uniforms.scale },
});
oldSlider.value = '0.8';
oldSlider.emit('input');
assert.equal(f.values.amount, 0.25);
assert.equal(oldSlider.listeners.get('input').size, 0);
assert.equal(f.container.children.length, 1);
f.container.children[0].children[1].value = '3.5';
f.container.children[0].children[1].emit('input');
assert.equal(f.values.scale, 3.5);
});
test('clearing removes rows and listeners but allows another style', () => {
const f = parameters();
const oldSlider = f.container.children[0].children[1];
f.controller.clear();
oldSlider.emit('input');
assert.equal(f.container.children.length, 0);
assert.deepEqual(f.order, []);
f.controller.render(f.options);
assert.equal(f.container.children.length, 2);
});
test('destroy is final and cannot clear a subsequent owner’s DOM', () => {
const f = parameters();
const oldSlider = f.container.children[0].children[1];
f.controller.destroy();
const nextOwner = new Element();
f.container.appendChild(nextOwner);
f.controller.render(f.options);
f.controller.clear();
f.controller.destroy();
oldSlider.emit('input');
assert.deepEqual(f.container.children, [nextOwner]);
assert.deepEqual(f.order, []);
});