reactjs 带有React的材料UI:如何使用圆角设计风格< Autocomplete/>

pwuypxnk  于 2022-12-03  发布在  React
关注(0)|答案(2)|浏览(160)

我一直是谷歌搜索栏的粉丝,它有漂亮的圆角和足够的文本填充。

我尝试使用Material UI的<Autocomplete/>组件复制这种风格,但似乎做不到。我使用的是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;

上面的代码应该按原样运行--其中还有一个axios调用,用于填充自动完成结果。

我尝试过各种方法来获得<SearchIcon />图标前缀,但都没有成功,但如果我能找到填充它的方法,我真的会很高兴。你可以在谷歌截图中看到自动完成功能是如何与框对齐的,但在我的版本中,border-radius只是将元素舍入,因此它不再与下拉列表对齐。
我是Material UI的新手,所以我仍然不太清楚如何使用这些样式,但我认为问题是边框是由一些内部元素绘制的,尽管我可以在组件本身的全局CSS上设置borderRadius:

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

我似乎不能设置填充或边框的任何地方。我也尝试设置风格与sx,但它没有任何作用。

g6ll5ycj

g6ll5ycj1#

你必须查看自动完成的css类,并在你的组件中覆盖它们,或者在你的主题中使用它们,如果你使用的话。

<Autocomplete
    componentsProps={{
      paper: {
        sx: {
          width: 350,
          margin: "auto"
        }
      }
    }}
    id="Hello"
    notched
    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..."
        sx={{
          "& .MuiOutlinedInput-root": {
            borderRadius: "50px",

            legend: {
              marginLeft: "30px"
            }
          },
          "& .MuiAutocomplete-inputRoot": {
            paddingLeft: "20px !important",
            borderRadius: "50px"
          },
          "& .MuiInputLabel-outlined": {
            paddingLeft: "20px"
          },
          "& .MuiInputLabel-shrink": {
            marginLeft: "20px",
            paddingLeft: "10px",
            paddingRight: 0,
            background: "white"
          }
        }}
      />
    )}
  />

沙盒:https://codesandbox.io/s/infallible-field-qsstrs?file=/src/Search.js

uubf1zoe

uubf1zoe2#

我试图弄清楚如何排列边缘 (弄清楚了,见更新),但这是我如何能够插入搜索图标,通过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 >
            )}
            ...
/>

忽略颜色和其他样式,但它看起来是这样的:

更新

我能够通过CSS控制border-radius并将左下角和右下角设置为0,顶部设置为20px来排列边缘。
下面是一个演示:

以下是我在css中所做的修改。我还保留了底部边框,这样在搜索和结果之间就有了一个分界线,但是如果你喜欢的话,你可以随意设置样式。(另外,我正在使用scss,所以我在顶部将颜色声明为变量)。

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;
}

相关问题