如何为antd Select设置自定义样式?

Posted

技术标签:

【中文标题】如何为antd Select设置自定义样式?【英文标题】:How to set custom style to antd Select? 【发布时间】:2020-02-17 21:40:02 【问题描述】:

我想自定义 antd Select。当用户点击 Select 时,antd Option 应该显示在 antd Select 上方,而不是显示在 Select 下方

antd Select: https://ant.design/components/select/

预期行为:1

实际行为:2

JSX

import  FaPlane, FaWater  from "react-icons/fa";

//outside of class
const shipmentType = 
  sea: [
     name: "FCL", desc: "FULL CONTAINER LOAD" ,
     name: "LCL", desc: "LESS CONTAINER LOAD" 
  ],
  air: [ name: "AIR", desc: "AIR DELIVERY" ]
;


//inside of class

render()
       return(
              <Select
              className="container-dropdown"
              onChange=this.onSelectChange
              defaultValue=
                  <DisplayContainer data=shipmentType.sea[0] />
              
              key= shipmentType.sea[0]
            >
              <Option value=shipmentType.sea[0].name>
                <DisplayContainer data=shipmentType.sea[0] />
              </Option>
              <Option value=shipmentType.sea[1].name>
                <DisplayContainer data=shipmentType.sea[1] />
              </Option>
            </Select>
          );


DisplayContainer.js 组件

const DisplayContainer = ( data ) => 
  return (
    <div
      style=
        width: "120px",
        height: "45px",
        display: "flex",
        flexFlow: "column",
        justifyContent: "center",
        alignItems: "center"
      
    >
      <span
        style=
          display: "block",
          fontSize: "8px",
          padding: "5px 0px 0px 10px"
        
      >
        data.desc
      </span>

      <span style= padding: "2px 0px 0px 14px" >
        data.name === "AIR" ? <FaPlane /> : <FaWater />
        <span
          style= display: "inline", marginLeft: "14px", fontSize: "16px" 
        >
          data.name
        </span>
      </span>
    </div>
  );
;

App.css

.container-dropdown 
    height: 53px;
    width: 140px;
    border: 0px solid white;
    border-radius: 0px;
    cursor: pointer;
    font-size: 18px;
    margin: 0px;
    padding: 0px;

custom-antd.css

.ant-select-selection.ant-select-selection--single 
    border-radius: 0px 8px 8px 0px;
    height: 53px;


.ant-select-selection-selected-value 
    height: 53px;
    padding: 0px;
    margin: 0px;


.ant-select-selection__rendered 
    padding: 0px;
    margin: 0px;


.ant-select-dropdown-menu.ant-select-dropdown-menu-root.ant-select-dropdown-menu-vertical 
    padding: 0px;
    margin: 0px;


.ant-select-dropdown-menu-item 
    padding: 0px;
    margin: 0px;

我怎样才能做到这一点?我已经花了几个小时的时间。但我无法成功。我会感激你的。谢谢

编辑 01:

当用户点击Select 框时

我希望顶部的Option(即FCL)像这样覆盖Select 框:

我不希望Options(即FCLLCL)都显示在Select 框下方:

【问题讨论】:

【参考方案1】:

我相信我已经能够非常接近您想要实现的目标。以下是更新后的 custom-antd.css 文件。

.ant-select-selection-selected-value 
  border-radius: 0px 8px 8px 0px;
  height: 53px;


.ant-select-selection.ant-select-selection--single 
  height: 53px;


.ant-select-selection.ant-select-selection--single
  > div
  > div
  > div
  > div
  + div 
  margin-top: -5px;
  padding: 4px 5px 5px 14px !important;


.ant-select-selection.ant-select-selection--single > div > div > div > div 
  margin-top: -20px;


.ant-select-selection.ant-select-selection--single[aria-expanded="true"]
  > div
  > div
  > div
  > div 
    margin-top: -10px;


 /*style for when the menu is expanded: show shipment description above icon and name*/ 
.ant-select-selection.ant-select-selection--single[aria-expanded="true"]
    > div
    > div
    > div
    > div
    + div 
       margin-top: -15px;

完整的代码沙箱可以在here找到。

基本上,您想要做的是使用组合器来选择特定的div 的名称、描述等,这些 ant design 在其结构中嵌套得很深。

编辑

为了让下拉菜单根据当前选择的内容显示不同的数据(仅在选择 FCL 时显示 LCL,反之亦然),您可以使用 handleChange 函数过滤原始货件数据,以便返回所有当前未选择(即在选择 FCL 时显示 LCL without FCL)。通过将原始货件数据与第二个数组(过滤的菜单数据)一起存储在状态中,您可以使用/更新第二个数组以供您选择。

这是你的状态。

  this.state = 
     shipmentArr: [],
     shipmentType: 
        sea: [
           name: "FCL", desc: "FULL CONTAINER LOAD" ,
           name: "LCL", desc: "LESS CONTAINER LOAD" 
        ],
        air: [ name: "AIR", desc: "AIR DELIVERY" ]
     
  ;

这是新的handleChange

handleChange = value => 
   var newShipmentType = this.state.shipmentType.sea.filter(x => 
     return x.name !== value;
   );
   this.setState(
     shipmentArr: newShipmentType
   );
;

这里是componentDidMount(使用handleChange)。

componentDidMount = () => 
    this.handleChange(this.state.shipmentType.sea[0].name);
;

以下是更新后的Select 组件。

<Select
    className="container-dropdown"
    onChange=this.handleChange
    open=true // USE THIS FOR DEBUGGING.
    defaultValue=
      <DisplayContainer data=this.state.shipmentType.sea[0] />
    
    key=this.state.shipmentArr[0]
  >
    this.state.shipmentArr.map(x => 
      return (
        <Option value=x.name>
          <DisplayContainer data=x />
        </Option>
      );
    )
  </Select>

查看完整的updated codepen。

【讨论】:

请参阅我已更新问题。我又添加了两张图片。很抱歉造成混乱。 这非常接近我想要的。我会接受它。非常感谢。 @blueseal 没问题。我不确定它是否在 repo 中可用。我只是检查了他们。 Ant Design 使用了很多嵌套的 divspan,只是花了一些时间在嵌套元素中查找需要定位的元素。 @MattCroak 如果你有空闲时间,你介意回答一下***.com/q/58772432/5124488 吗? @blueseal 我刚刚发布了一个答案:)

以上是关于如何为antd Select设置自定义样式?的主要内容,如果未能解决你的问题,请参考以下文章

如何为 .NET 项目自定义强制代码样式规则

如何为 .NET 项目自定义强制代码样式规则 #yyds干货盘点#

如何为 UINavigationBar 的 styleBar 创建自定义样式?

如何为 Vue.js 组件创建自定义样式属性

使用样式化组件自定义 antd 工具提示样式

如何为 UITabBarItem 设置自定义标题属性