Repository: material-ui
Issue: [Discussion] Support some (or maybe all?) non-integer values passed to `theme.spacing()`
Labels: new feature,discussion,package: system

### N.B.: This issue is a continuation of the discussion in #29526, as requested by @siriwatknp and @oliviertassinari
------
<br />

## Summary

Should we allow positive, non-integer values to be passed to `theme.spacing()`? And, if so, should we only allow "half-values" (e.g. `0.5`, `1.5`, `2.5`)? Or should we allow all positive non-integer values (e.g. `0.05`, `1.2`, etc.)?
<br />
<br />

## Original issue

In #29526, we addressed and resolved an issue (#29479) with non-integer values (e.g. `0.5`, `1.2`, etc.) being passed as parameters to `theme.spacing()`. Such values are invalid when `spacing` is an array, and their use in some MUI components was resulting in errors.

The fix was to replace all instances where MUI components were trying to pass decimal values to `theme.spacing()` with string interpolation and CSS `calc()`. 

So, something like this...
```
paddingLeft: theme.spacing(1.2),
```
...was changed to this:

```
paddingLeft: `calc(${theme.spacing(1)} * 1.2)`,
```
<br />
<br />

## Current behavior

[As per the documentation](https://mui.com/customization/spacing/#custom-spacing), `spacing` can be defined as:
- a number
```
createTheme({
  spacing: 2,
});
```
- a function
```
createTheme({
  spacing: (n) => `${0.25 * n}rem`,
});
```
- or an array
```
createTheme({
  spacing: [0, 4, 8, 16, 32, 64, 128, ...],
});
```

If `spacing` is defined as a number, non-integer decimal values can be safely passed to `theme.spacing()` and work as expected. The number in question is a coefficient. If, for instance, this coefficient is **K**, `theme.spacing(1.2)` calculates to 1.2 × **K**. The same can more or less be said for spacing when it is defined as a custom function, as shown above.

If, however, `spacing` is defined as an array, the parameters passed to `theme.spacing()` must be valid array indexes. Non-integer numbers are not valid indexes. When `spacing` is an array, and decimal values are provided to `theme.spacing()`, the values are ignored and an error message is displayed:
```
MUI: The `theme.spacing` array type cannot be combined with non integer values.You should either use an integer value that can be used as index, or define the `theme.spacing` as a number. 
```
![hzh3AAtUch](https://user-images.githubusercontent.com/18078610/140013121-aee3ae48-8d5a-46e0-9f46-2590bec46f4d.png)

The origin of this error message is another previous issue, #23187.
<br />
<br />

## Suggested change

@siriwatknp [suggested that, while the fix resolves the existing issue, it might make more sense to simply allow non-integer values to always be passed to `theme.spacing()`, even if `spacing` is an array](https://github.com/mui-org/material-ui/pull/29526#issuecomment-965994879). This would involve changing the logic in `createSpacing.ts` to do the calculation there, instead of forcing devs to write out the css `calc()` implementation each time.
> 2 solutions that I see
>
> 1. all of the components should never use theme.spacing(decimal) because we force the warning
> 2. remove the warning and fix createSpacing to support decimal if spacing array is specified.
>
> option 1 will hurt us in the long term because we might miss it in other components and some people will open the same issues, so I favor option 2.

@oliviertassinari [responded that non-integer parameters passed to `theme.spacing()` make sense for "half values" (e.g. `0.5`, `1.5`, `2.5`), but not for any other values (e.g. `1.2`, `2.35`, `0.075`)](https://github.com/mui-org/material-ui/pull/29526#issuecomment-966994855)
> 👍 for supporting half values: e.g. 0.5, 1.5. It's very handy when you have to split the spacing in two between margin-top and margin-bottom. It's also easy to compute when spacing is an array, the logic can be: theme.spacing[value * 2] / 2.
> 👎 for supporting 1.2. I personally think that theme.spacing() could warn against (in all the cases). To me, it doesn't make sense. It's probably better for the developers to hard code the value or uses calc in this case.