简体   繁体   English

使用 React 的 Material UI:如何设置样式<autocomplete />带圆角

[英]Material UI with React: How to style <Autocomplete/> with rounded corners

I've always been a fan of Google's search bar, with nice rounded corners and ample padding around the text.我一直是谷歌搜索栏的粉丝,它有漂亮的圆角和文本周围充足的填充。

在此处输入图像描述

I'm trying to replicate this style using Material UI's <Autocomplete/> component, but I can't seem to do it.我正在尝试使用 Material UI 的<Autocomplete/>组件复制这种样式,但我似乎做不到。 I'm using Next.js. What I have so far is:我正在使用 Next.js。我目前拥有的是:

import React, { useState, useEffect } from 'react';
import TextField from '@mui/material/TextField';
import Stack from '@mui/material/Stack';
import Autocomplete from '@mui/material/Autocomplete';
import { borderRadius, Box } from '@mui/system';
import SearchIcon from '@material-ui/icons/Search';


const LiveSearch = (props) => {

  const [jsonResults, setJsonResults] = useState([]);

  useEffect(() => {
    fetch(`https://jsonplaceholder.typicode.com/users`)
      .then(res => res.json())
      .then(json => setJsonResults(json));
  }, []);

  return (
      <Stack sx={{ width: 400, margin: "auto"}}>
        <Autocomplete
          id="Hello"
          getOptionLabel={(jsonResults) => jsonResults.name}
          options={jsonResults}
          noOptionsText="No results"
          isOptionEqualToValue={(option, value) => {
            option.name === value.name
          }}
          renderOption={(props, jsonResults) => (
            <Box component="li" {...props} key={jsonResults.id}>
              {jsonResults.name} - Ahhh
            </Box>
          )}
          renderInput={(params) => <TextField {...params} label="Search users..." />}
        />
                  

      </Stack>

  )
}

export default LiveSearch;

The above code should run as-is – there's an axios call in there to populate the autocomplete results too.上面的代码应该按原样运行——那里有一个 axios 调用来填充自动完成结果。

在此处输入图像描述

I've tried various way to get the <SearchIcon /> icon prefix inside the input with no success, but really I'd just be happy if I could figure out how to pad it.我已经尝试了各种方法来获取输入中的<SearchIcon />图标前缀,但没有成功,但如果我能弄清楚如何填充它,我真的会很高兴。 You can see in the google screenshot how the autocomplete lines up really well with the box, but in my version, the border-radius just rounds the element, and so it no longer lines up with the dropdown.你可以在谷歌截图中看到自动完成如何与框很好地对齐,但在我的版本中,border-radius 只是围绕元素,因此它不再与下拉列表对齐。

I'm new to Material UI, so I'm still not quite sure how to do these styles, but I think the issue is that the border is being drawn by some internal element, and although I can set the borderRadius on the component itself global CSS:我是 Material UI 的新手,所以我仍然不太确定如何做这些 styles,但我认为问题是边框是由一些内部元素绘制的,虽然我可以在组件本身上设置 borderRadius全球 CSS:

.MuiOutlinedInput-root {
  border-radius: 30px;
}

I can't seem to set the padding or borders anywhere.我似乎无法在任何地方设置填充或边框。 I've also tried setting style with sx but it does nothing.我也尝试过使用sx设置样式,但它什么也没做。

I'm trying to figure out how to line up the edges (figured it out, see update) , but this is how I was able to insert the Search icon, via renderInput and I got rid of the expand and collapse arrows at the end of the bar by setting freeSolo={true} (but this allows user input to not be bound to provided options).我试图弄清楚如何排列边缘(想通了,请参阅更新) ,但这是我能够通过renderInput插入搜索图标的方式,我在最后摆脱了展开和折叠箭头通过设置freeSolo={true} (但这允许用户输入不绑定到提供的选项)。

import { Search } from '@mui/icons-material';
import { Autocomplete, AutocompleteRenderInputParams, InputAdornment } from '@mui/material';

...
<Autocomplete
            freeSolo={true}
            renderInput={(renderInputParams: AutocompleteRenderInputParams) => (
                <div ref={renderInputParams.InputProps.ref}
                    style={{
                        alignItems: 'center',
                        width: '100%',
                        display: 'flex',
                        flexDirection: 'row'
                    }}>
                    <TextField style={{ flex: 1 }} InputProps={{
                        ...renderInputParams.InputProps, startAdornment: (<InputAdornment position='start'> <Search /> </InputAdornment>),
                    }}
                        placeholder='Search'
                        inputProps={{
                            ...renderInputParams.inputProps
                        }}
                        InputLabelProps={{ style: { display: 'none' } }}
                    />
                </div >
            )}
            ...
/>

Ignore the colors and other styling, but this is what it looks like:忽略 colors 和其他样式,但这就是它的样子:

在此处输入图像描述

Update更新

I was able to line up the edges by controlling the border-radius via css and setting the bottom left and right to 0 and top ones to 20px.我能够通过 css 控制border-radius并将左下角和右下角设置为 0,将顶部设置为 20px 来对齐边缘。

Here's a demo:这是一个演示:

模拟谷歌搜索的 Mui Autocomplete 演示

Here are the changes I had to make in css. I also left the bottom border so there is a division between the search and the results, but you can style if however you like.这是我必须在 css 中进行的更改。我还保留了底部边框,以便在搜索和结果之间进行划分,但您可以根据需要设置样式。 (Also I'm using scss so I declared colors as variables at the top). (我也在使用 scss,所以我在顶部声明了 colors 作为变量)。

div.MuiAutocomplete-root div.MuiOutlinedInput-root { /* Search bar when not in focus */
  border-radius: 40px;
  background-color: $dark-color;
}

div.MuiAutocomplete-root div.MuiOutlinedInput-root.Mui-focused { /* Search bar when focused */
  border-radius: 20px 20px 0px 0px !important;
}

div.MuiAutocomplete-root div.Mui-focused fieldset { /* fieldset element is what controls the border color. Leaving only the bottom border when dropdown is visible */
  border-width: 1px !important;
  border-color: transparent transparent $light-gray-color transparent !important;
}

.MuiAutocomplete-listbox { /* To control the background color of the listbox, which is the dropdown */
  background-color: $dark-color;
}

div.MuiAutocomplete-popper div { /* To get rid of the rounding applied by Mui-paper on the dropdown */
  border-top-right-radius: 0px;
  border-top-left-radius: 0px;
}

You have to look at the autocomplete css classes and override them in your component or use them in your theme , if you use one.您必须查看自动完成 css类并在您的组件中覆盖它们或在您的主题中使用它们(如果您使用它们)。

eg to add the left padding例如添加左侧填充

          <TextField
            {...params}
            label="Search users..."
            sx={{
              "& .MuiAutocomplete-inputRoot": {
                paddingLeft: "20px !important"
              },
              "& .MuiInputLabel-outlined": {
                paddingLeft: "20px"
              },
              "& .MuiInputLabel-shrink": {
                paddingLeft: 0
              }
            }}
          />

You simply add border radius to fieldset:您只需将边框半径添加到字段集:

<Autocomplete
  sx={{ '& fieldset': { borderRadius: 33 }}}
/>

Codesandbox 代码沙盒

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM