Repository: streamlit/streamlit

Issue:
Remove number_input -/+ step toggles option
Is there an option to remove the -/+ number_input step toggles? If not, I would suggest that for a future release. Thank you! 

Also, is it possible to increase the precision? 

Right now I am just using a text_input and type casting to float to get around this.

---

Community voting on feature requests enables the Streamlit team to understand which features are most important to our users.

**If you'd like the Streamlit team to prioritize this feature request, please use the 👍 (thumbs up emoji) reaction in response to the initial post.**


Discussion:
Hi @ajberlier ,

There's no option to remove the +/- toggles at the moment. I'll leave this issue open as a feature request!

You can use the `step` attribute to  modify the precision of the toggles. If you just want to be able to enter floats in general, use a float as the initial value.

`st.number_input("number input", step=0.1, value=1.0)`

The default `step` and `value` are floats already.

`st.number_input("number input")`
@jrhone 

I am not sure how hard it would be to implement, but I think a good way to use this (currently non-existent) feature would be to set step=0.
Hi @RedFrez , I like the idea suggestion :)

Pinging our product team to ensure they have eyes on this @nthmost
One reason to having the ability to remove the buttons, is if the page will be printed out. In "paper" format the buttons have no value, and just add some visual clutter to the page. 

With a live site, if reviewing the data is more than altering it, then you may want to reduce the usability/visibility of the buttons. 

__My idea for implementation:__
- Anyone who cares about altering the steps of the buttons would not be setting them to 0. This also passes my logic test of if you don't want buttons, then you want the steps to nothing, null, or 0. 

- The step could be converted to receive a `null` value, but that would require altering the Proto and more logic in order to process how it should be handled.

- There could be another parameter added to number_input, but this would add overall complexity to the code, which I think is unnecessary. This could also be in the future if desired with minimal impact.

Using the `step=0` option, only adds two additional lines to the number_input widget, not taking into account the lines added for testing. Since it checks `element.step` for conditional rendering of the buttons, it has no impact on how `step` is processed or used for any other aspect of the input.

I thought it was important to still allow for use of the up and down arrows for controlling the input. Since `0` is a Falsy value, it will still generate the default steps based on number type of the input.
@ajberlier : Curious to hear, what is your use case for removing the -/+ number_input step toggles?
For us, we would use as a 'free' number input and not as a "range".
For example:
`st.number_input("How much did it cost?", min_value=0.0, step=0.01)`
We want from the user that write out the number in the specified format (like `12499.99`), where '+' and '-' buttons has no meaning.   
Hi @asaini ,

I thought I would describe a common use-case of mine for removing the step buttons. A lot of my Streamlit apps include some preliminary data manipulation functionality, like inputting various minimum/maximum constraints which then get applied to, say, columns of a dataframe. For one app, I'd like to be able to do this in the sidebar, since it isn't the main functionality of the app, and having it centered would clutter the interface.

I have found that the best way to accomplish this, from a layout perspective, is to use `st.beta_columns` and populate 2 columns with `st.number_input` for the minimum and maximum values. These 2 column "units" are then placed in rows for as many constraints are needed.

However, when these columns are placed in the sidebar, the low sidebar width causes the increment/decrement buttons to occupy more screen space than the actual input field. The user cannot see the entirety of the numbers they are entering, and the layout is cluttered and distracting. I see three workarounds, each problematic in their own way:

1. Use `st.slider`. This works to an extent, but the flaw with using sliders occurs when the slider range is extracted from the range of the data itself. Sometimes, extreme outliers in the data will skew one end of the slider so far to the left or right side that a majority of the data is compressed to within some small % of the slider space. This is frustrating, and often means that in the course of interaction the user has to move the ends of the sliders so close together that the numbers bleed together and obscure each other (the numbers which float above the little draggable circle). Additionally, if there are a sufficient number of digits in the maximum value for slider, then the sidebar gains a horizontal scroll bar (at least in Firefox) since these digits go off the edge of the sidebar.
2. Use `st.text_input`. This removes the visual clutter of the increment/decrement buttons present with `st.number_input`, but is essentially untenable. It requires manually handling numeric input validation, and in addition losing out on the real-time validation and protection that `st.number_input` provides, it also leaves the user without the clean hint regarding the min/max value specification (i.e., the pop-up message saying "Please select a value that is no less/more than *X*" which occurs when you enter an out-of-range value into an `st.number_input`).
3. [Increasing the sidebar width](https://github.com/streamlit/streamlit/issues/2058). This allows the user to see the numbers in each field, but at the expense of the visual experience of the app. It means that the sidebar is no longer "in the background", as it competes with the main space and pushes it further to the right side of the screen. On a larger screen with high DPI, this can look mostly OK, but becomes a problem at lower resolutions or aspect ratios.

In sum, I feel that having an option to just simply not render the increment/decrement buttons on `st.number_input` would allow for more compact side-by-side layouts by taking better advantage of screen estate. I don't have anything to suggest regarding implementation, but this is just my use-case. Anyways--I hope this feels concrete and well motivated. Let me know if you have any questions.
@jrhone @kmcgrady are there any news on this 2 year old much wanted feature? :)
I'm also interested in any updates
Any update on this request? As mentioned, the + and - buttons sometimes occupies a large fraction of the number_input field, making it impossible to read the  number typed.
@pkla described my use case perfectly: putting more than one `st.number_input` column in a typical sidebar means that the entire number is obscured by the buttons. `st.slider` is a poor alternative if the data has a large spread.

I would like to add that a user might be tempted to quickly click the button multiple times instead of changing the value directly. If the input is tied to some slower-than-instantaneous operation, it results in multiple refreshes and poor performance.

When doing multiple clicks I've also noticed some additional instability: the page reloads slower and slower until the buttons are no longer accessible; after it comes back the widget ends up with the default state, and the computation with some unknown state from when the button was last clicked.

In summary, the buttons offer many drawbacks for IMO very little benefit.

edit: One more thing. We've noticed that if the step is not explicitly defined and the value is an `int`, the initial step is 1, but clicking the button a few times can make it lose track of the value and go back to decimal changes.
I don't really like using `unsafe_allow_html` on markdowns, but I've found a very simple solution for being unable to disable the step function:
```
def remove_step_number_input():
    st.markdown("""
                <style>
                    .css-qn8ina {display: none;}
                </style>""",
                unsafe_allow_html=True)
```
If that doesnt work directly, you might need to get the css selector from your st.number_input step buttons:

![image](https://user-images.githubusercontent.com/48677316/210282557-f75bbe99-c3bf-47c8-b5fd-e59c9d9013c3.png)

It completely disables the step buttons as they become unclickable and invisible.
For anyone still running into this issue and wants a robust way to disable the +/- buttons, here you go:

```python
st.markdown("""
<style>
    button.step-up {display: none;}
    button.step-down {display: none;}
    div[data-baseweb] {border-radius: 4px;}
</style>""",
unsafe_allow_html=True)
```

The method above is preferable to the solution in https://github.com/streamlit/streamlit/issues/894#issuecomment-1369252559 because it does not rely on looking up the random CSS class names that can change from one build to another. The CSS classes above are constant and will not change from one build to the next. Styling will also ensure that the highlighted borders match up.

Tested against `streamlit==1.18.1` but it should work for any recent version(s). 

------

In general though, I completely agree that this should be a feature in `streamlit` to easily toggle that option in the `number_input` widget. The [comments](https://github.com/streamlit/streamlit/issues/894#issuecomment-1144803716) by @matkozak are spot on and I ran into all kinds of app instability and poor performance issues when users interact with these benefits. All for very little user experience benefit. 

Not only should there be an option to disable these buttons, I would argue that having these buttons displayed for a number input form field should certainly **not be the default**...  Users should opt into showing these buttons. This is a "number input" (i.e. user types) widget, not a "number stepper" widget.
I am very interested on this, too, and posted [here](https://discuss.streamlit.io/t/number-input-without-stepper/39907).

- 2019-Dec, ajberlier opened issue #894
- 2021-Feb, CFrez created pull-request #2791 and proposed an implementation of the freature
- 2021-Mar, somebody from the product team denied the request and closed it
- 2021-Sep, ks00x opened issue #3630; it was marked as duplicate of #894 and closed
- 2022-   , users continue to show interest on this feature request
- 2023-Mar, still _no cigar_ 

@walsha2 :  Newbie, here; can do I use your proposed solution in my program? How? Where do I place it? 
> @walsha2 : Newbie, here; can do I use your proposed solution in my program? How? Where do I place it?

@gsal Place the code snippet shown in https://github.com/streamlit/streamlit/issues/894#issuecomment-1433112038 **anywhere** in your streamlit app. That should be all there is to it!

Once you do that all your `number_input` widgets will not show the `+/-`. Please note that this is an all or nothing "solution". You cannot selectively turn this on for some `number_input` widgets but not others.

Again, the best solution long term will be for a flag to be added to the `number_input` (i.e. a core `streamlit` code change) that allows users to optionally enable this "step" +/- feature if they desire. [This](https://github.com/streamlit/streamlit/issues/894#issuecomment-1433112038) is simply a workaround until that is incorporated into streamlit.
need this too

Resolving patch:
diff --git a/e2e/scripts/st_number_input.py b/e2e/scripts/st_number_input.py
--- a/e2e/scripts/st_number_input.py
+++ b/e2e/scripts/st_number_input.py
@@ -47,3 +47,9 @@ def on_change():
     st.number_input("number input 9", key="number_input9", on_change=on_change)
     st.write('value 9: "', st.session_state.number_input9, '"')
     st.write("number input changed:", "number_input_changed" in st.session_state)
+
+[col1, col2, col3, col4, col5, col6] = st.columns(6)
+
+with col1:
+    i10 = st.number_input("number input 10", max_value=10)
+    st.write('value 10: "', i10, '"')


Test patch:
diff --git a/frontend/lib/src/components/widgets/NumberInput/NumberInput.test.tsx b/frontend/lib/src/components/widgets/NumberInput/NumberInput.test.tsx
--- a/frontend/lib/src/components/widgets/NumberInput/NumberInput.test.tsx
+++ b/frontend/lib/src/components/widgets/NumberInput/NumberInput.test.tsx
@@ -21,6 +21,7 @@ import {
 } from "@streamlit/lib/src/proto"
 import React from "react"
 import { mount, shallow } from "@streamlit/lib/src/test_util"
+import { StyledInputControls } from "@streamlit/lib/src/components/widgets/NumberInput/styled-components"
 import { Input as UIInput } from "baseui/input"
 import { WidgetStateManager } from "@streamlit/lib/src/WidgetStateManager"
 
@@ -33,7 +34,7 @@ const getProps = (elementProps: Partial<NumberInputProto> = {}): Props => ({
     hasMax: false,
     ...elementProps,
   }),
-  width: 0,
+  width: 300,
   disabled: false,
   widgetMgr: new WidgetStateManager({
     sendRerunBackMsg: jest.fn(),
@@ -452,5 +453,19 @@ describe("NumberInput widget", () => {
       expect(wrapper.state("value")).toBe(2)
       expect(stepUpButton(wrapper).prop("disabled")).toBe(true)
     })
+
+    it("hides stepUp and stepDown buttons when width is smaller than 120px", () => {
+      const props = getIntProps({ default: 1, step: 1, max: 2, hasMax: true })
+      const wrapper = shallow(<NumberInput {...props} width={100} />)
+
+      expect(wrapper.find(StyledInputControls).exists()).toBe(false)
+    })
+
+    it("shows stepUp and stepDown buttons when width is bigger than 120px", () => {
+      const props = getIntProps({ default: 1, step: 1, max: 2, hasMax: true })
+      const wrapper = shallow(<NumberInput {...props} width={125} />)
+
+      expect(wrapper.find(StyledInputControls).exists()).toBe(true)
+    })
   })
 })