Skip to content

Odd behaviour with start step parameters in mo.ui.number #9106

@altohr

Description

@altohr

Describe the bug

When using mo.ui.number element we can set the parameters start, step and value. They all have some strange dependencies on each other which seems rather odd.

Unexpected initializing behaviour:

When setting parameter start smaller than step and setting a value the start parameter is influencing the set value.

Example1:

number = mo.ui.number(start=1.25557, stop=20, label="Number", step=0.001, value=2.23)

Intially the value shown in the input element: 2.2296
When getting number.value then the output is: 2.23

Expected behaviour

  • Initial value shown in input field is 2.23 and not influenced by start or step parameter.
  • number.value is equal to shown input value

Example2:

number = mo.ui.number(start=1, stop=20, label="Number", step=0.001, value=2.23345)

Intially the value shown in the input element: 2.233
When getting number.value then the output is: 2.23345

Expected behaviour

  • Shown input field value should not be dependent on step parameter
  • Value shown in input field should be 2.23345 same as number.value

Value can not be set bellow step size

The precision of the user input value of mo.number.ui and the step size are not separated. This is not what I would expect. There is nothing like that described in the documentation and I would expect that the user can still set any number he wants even a number smaller than the step size.

Example3:

number = mo.ui.number(start=1, stop=20, label="Number", step=0.01, value=2.23345)
  1. User sets value to 2.3377
  2. Input is set to 2.24

Expected behaviour

  1. User sets value to 2.3377
  2. Input is set to 2.3377

Example4:

Another problem is the start value is also changing this behaviour even further:

number = mo.ui.number(start=1.222, stop=20, label="Number", step=0.01, value=2.23345)
  1. User sets value to 2.23111
  2. Input is set to 2.232

Expected behaviour

  1. User sets value to 2.23111
  2. Input is set to 2.23111

Will you submit a PR?

  • Yes

Environment

Details
{
  "marimo": "0.21.0",
  "editable": false,
  "location": "numberexample/.venv/lib/python3.12/site-packages/marimo",
  "OS": "Darwin",
  "OS Version": "25.3.0",
  "Processor": "arm",
  "Python Version": "3.12.12",
  "Locale": "--",
  "Binaries": {
    "Browser": "146.0.7680.178",
    "Node": "v23.1.0",
    "uv": "0.8.22 (Homebrew 2025-09-23)"
  },
  "Dependencies": {
    "click": "8.3.2",
    "docutils": "0.22.4",
    "itsdangerous": "2.2.0",
    "jedi": "0.19.2",
    "markdown": "3.10.2",
    "narwhals": "2.19.0",
    "packaging": "26.0",
    "psutil": "7.2.2",
    "pygments": "2.20.0",
    "pymdown-extensions": "10.21.2",
    "pyyaml": "6.0.3",
    "starlette": "1.0.0",
    "tomlkit": "0.14.0",
    "typing-extensions": "4.15.0",
    "uvicorn": "0.44.0",
    "websockets": "16.0"
  },
  "Optional Dependencies": {
    "loro": "1.10.3"
  },
  "Experimental Flags": {}
}

Code to reproduce

import marimo

__generated_with = "0.21.0"
app = marimo.App(width="medium")


@app.cell
def _():
    import marimo as mo

    return (mo,)


@app.cell
def _(mo):
    mo.md(
        """
        ## Unexpected initializing behaviour:
        When setting parameter `start` smaller than `step` and setting a `value` the `start` parameter is influencing the set `value`.

        ### Example1: 
        Initially the value shown in the input element: `2.2296`
        When getting `number.value` then the output is: `2.23`

        **Expected behaviour**
        - Initial value shown in input field is 2.23 and not influenced by `start` or `step` parameter.
        - `number.value` is equal to shown input value
        """
    )
    return


@app.cell
def _(mo):
    number1 = mo.ui.number(start=1.25557, stop=20, label="Number 1", step=0.001, value=2.23)
    return (number1,)


@app.cell
def _(mo, number1):
    mo.hstack([number1, mo.md(f"Has value: {number1.value}")])
    return


@app.cell
def _(mo):
    mo.md(
        """
        ### Example2:
        Initially the value shown in the input element: `2.233`
        When getting `number.value` then the output is: `2.23345`

        **Expected behaviour**
        - Shown input field value should not be dependent on `step` parameter
        - Value shown in input field should be `2.23345` same as `number.value`
        """
    )
    return


@app.cell
def _(mo):
    number2 = mo.ui.number(start=1, stop=20, label="Number 2", step=0.001, value=2.23345)
    return (number2,)


@app.cell
def _(mo, number2):
    mo.hstack([number2, mo.md(f"Has value: {number2.value}")])
    return


@app.cell
def _(mo):
    mo.md(
        """
        ## Value can not be set below step size
        The precision of the user input value of `mo.number.ui` and the `step` size are not separated. This is not what I would expect. There is nothing like that described in the documentation and I would expect that the user can still set any number he wants even a number smaller than the `step` size.

        ### Example3:
        1. User sets value to `2.3377`
        2. Input is set to `2.24`

        **Expected behaviour**
        1. User sets value to 2.3377
        2. Input is set to 2.3377
        """
    )
    return


@app.cell
def _(mo):
    number3 = mo.ui.number(start=1, stop=20, label="Number 3", step=0.01, value=2.23345)
    return (number3,)


@app.cell
def _(mo, number3):
    mo.hstack([number3, mo.md(f"Has value: {number3.value}")])
    return


@app.cell
def _(mo):
    mo.md(
        """
        ### Example4:
        Another problem is the start value is also changing this behaviour even further:

        1. User sets value to `2.23111`
        2. Input is set to `2.232`

        **Expected behaviour**
        1. User sets value to `2.23111`
        2. Input is set to `2.23111`
        """
    )
    return


@app.cell
def _(mo):
    number4 = mo.ui.number(start=1.222, stop=20, label="Number 4", step=0.01, value=2.23345)
    return (number4,)


@app.cell
def _(mo, number4):
    mo.hstack([number4, mo.md(f"Has value: {number4.value}")])
    return


if __name__ == "__main__":
    app.run()

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions