@@ -70,6 +70,8 @@ export default class ExpressionList {
7070 if ( functions . length === 0 ) {
7171 if ( this . renderedItems . size === 0 ) {
7272 this . container . innerHTML = '<div style="padding: 1rem; color: var(--color-text-weak);">No expressions added</div>' ;
73+ // Ensure button is still visible after clearing innerHTML
74+ this . ensureButtonPosition ( ) ;
7375 }
7476 return ;
7577 }
@@ -91,6 +93,9 @@ export default class ExpressionList {
9193
9294 // 4. Reorder items to match function order
9395 this . reorderItems ( functions ) ;
96+
97+ // 5. Ensure add button is always at the end
98+ this . ensureButtonPosition ( ) ;
9499 }
95100
96101 /**
@@ -303,6 +308,9 @@ export default class ExpressionList {
303308
304309 // Append to container
305310 this . container . appendChild ( item ) ;
311+
312+ // Ensure button stays at the end
313+ this . ensureButtonPosition ( ) ;
306314 }
307315
308316 /**
@@ -367,11 +375,15 @@ export default class ExpressionList {
367375 value : value ,
368376 showInputs : false ,
369377 onChange : ( newValue ) => {
378+ // Format the value to the nearest 0.1
379+ const roundedValue = Math . round ( newValue / 0.1 ) * 0.1 ;
380+ const formattedValue = Number ( roundedValue . toFixed ( 1 ) ) ;
381+
370382 // Update Control State
371- StateManager . set ( `controls.${ varName } ` , newValue , { silent : true } ) ;
383+ StateManager . set ( `controls.${ varName } ` , formattedValue , { silent : true } ) ;
372384
373385 // Update Expression Text to match
374- const newExpr = `${ varName } = ${ newValue } ` ;
386+ const newExpr = `${ varName } = ${ formattedValue } ` ;
375387
376388 // Update local input value immediately for responsiveness
377389 if ( item . inputEl ) item . inputEl . value = newExpr ;
@@ -380,7 +392,7 @@ export default class ExpressionList {
380392 this . updateExpression ( func . id , newExpr ) ;
381393
382394 // Publish event for graph
383- EventBus . publish ( 'controls:updated' , { [ varName ] : newValue } ) ;
395+ EventBus . publish ( 'controls:updated' , { [ varName ] : formattedValue } ) ;
384396 }
385397 } ) ;
386398
@@ -462,6 +474,9 @@ export default class ExpressionList {
462474
463475 // Remove from map
464476 this . renderedItems . delete ( id ) ;
477+
478+ // Ensure button stays at the end
479+ this . ensureButtonPosition ( ) ;
465480 }
466481
467482 /**
@@ -492,6 +507,19 @@ export default class ExpressionList {
492507 }
493508 }
494509
510+ /**
511+ * Ensure the add button is always positioned at the end of the container
512+ */
513+ ensureButtonPosition ( ) {
514+ if ( ! this . addButton || ! this . container ) return ;
515+
516+ // If button is not the last child, move it to the end
517+ const lastChild = this . container . lastElementChild ;
518+ if ( lastChild !== this . addButton ) {
519+ this . container . appendChild ( this . addButton ) ;
520+ }
521+ }
522+
495523 /**
496524 * Escape HTML to prevent XSS
497525 * @param {string } text - Text to escape
0 commit comments