Support a valueRender prop for Select
What problem does this feature solve?
More control over the way selected values are shown in multi-selects. There are use cases where we do not want to display tags, for example when we just want to show comma separated values, truncated with an ellipsis. Analog to MUI Select's renderValue
What does the proposed API look like?
Support a valueRender prop allows replacing the content inside .ant-select-selection-overflow div, giving control to how you want to display the array of selected values.
<Select
className="my-select"
mode="multiple"
options={[{
label: 'Administration category A',
value: 1,
}, {
label: 'Administration category B',
value: 2,
}, {
label: 'Administration category C',
value: 3,
}]}
defaultValue={[1,2]}
valueRender={values => `${values.map(value => value.label).join(', ')}`}
This would yield the below HTML
<div class="my-select ant-select ant-select-multiple">
<div class="ant-select-selector">
<div class="ant-select-selection-wrap">
<div class="ant-select-selection-overflow">
Administration category A, Administration category B
</div>
</div>
</div>
</div>
Which we can style to achieve the overflow ellipsis and a simplified text value display
.my-select.ant-select-multiple .ant-select-selector .ant-select-selection-wrap .ant-select-selection-overflow {
white-space: nowrap;
text-overflow: ellipsis;
}
Thank you for your feature request regarding the valueRender prop for the Select component in Ant Design. This feature would indeed provide more flexibility in displaying selected values in multi-select scenarios, allowing for custom rendering such as comma-separated values with ellipsis.
Your proposal to introduce a valueRender prop is noted, and it will be considered by the team. This prop would allow developers to customize the display of selected values, enhancing the user interface according to specific needs.
If you have any further questions or additional details to provide, feel free to comment here.
🪧 Tips
For further assistance, please describe your question in the comments and @petercat-assistant to start a conversation with me.
Yes, I think your need is very meaningful, and I also took a look at the <Select /> component documentation of antd. The current tagRender and labelRender both cannot achieve combined customization.
The <Select /> should refer to the <Cascader /> and provide a displayRender prop to support this behavior.
label is all you need.
There is an internal method that can directly modify the selector trigger, allowing for customized display content.
import React from "react";
import { Input, Select } from "antd";
const MSelect = Select as any;
const options = [
{
label: "A",
value: "a",
},
{
label: "B",
value: "b",
},
{
label: "C",
value: "c",
},
];
const App = () => {
const [value, setValue] = React.useState<string[]>();
const displayValue = options
.filter((item) => value?.includes(item.value))
.map((item) => item.label)
.join(", ");
return (
<>
<MSelect
getRawInputElement={() => (
<Input
readOnly
variant="filled"
value={displayValue}
style={{
width: "auto",
minWidth: 200,
}}
/>
)}
value={value}
onChange={setValue}
mode="multiple"
options={options}
>
<div style={{ width: 120, height: 120, background: "red" }}></div>
</MSelect>
</>
);
};
export default App;
https://github.com/user-attachments/assets/8933c8f3-e6f3-4141-a3b2-fdc1b7dc48ab
https://ant.design/components/select#select-demo-option-render Did you mean this?
@Wxh16144 Thank you for thinking along but I think using getRawInputElement to overwrite the underlying Input adds unnecessary complexity, extra state management and loses a bulk of the Select out-of-the-box functionality. In practice I would have to carefully reassign all validation props, mimic the dropdown toggle, implement the clear icon + functionality etc.
There is an internal method that can directly modify the selector trigger, allowing for customized display content.
@afc163 Can you clarify your comment please? How can the label achieve a multiple Select value being displayed as "Administration A, Administr..." without the tags?
For the time being this is a "hacky" workaround I've come up with:
<Select
className="my-select"
mode="multiple"
options={[{
label: 'Administration category A',
value: 1,
}, {
label: 'Administration category B',
value: 2,
}, {
label: 'Administration category C',
value: 3,
}]}
maxTagCount={0}
maxTagPlaceholder={(omittedValues)=> {
const valueString = omittedValues.map(omittedValue => omittedValue.label).join(', ')
return <Tooltip title={valueString}>{valueString}</Tooltip>
}}
/>
Coupled with scss to overwrite Ant Design's attempt to leave space for tags + search
.my-select.ant-select-multiple {
height: 32px;
max-height:32px;
.ant-select-selector {
&:after{
margin: 0;
line-height:21px;
}
.ant-select-selection-wrap {
align-self:center;
&:after{
margin-block:0;
margin: 0;
line-height:21px;
}
.ant-select-selection-overflow {
white-space: nowrap;
text-overflow: ellipsis;
}
.ant-select-selection-overflow-item-suffix {
position: absolute;
right: 0;
margin-block: 0;
}
.ant-select-selection-item {
background: none;
}
}
}
}
I realise Ant Design is a design system, but flexibility in allowing users to divert from the default tag rendering would be very welcome and. In many real-world scenarios even necessary. Below is an example from the dashboard I'm working on:
Since the first selected value was just 2 characters too long for the Select to fully show as a tag, we see no value information anymore whatsoever. To show the shorter labels when possible also requires maxTagCount="responsive" which as we know has a performance cost. My use case would be solved with the valueRender prop without having to hack scss and I dare to guess I'm not alone as most other UI systems (MUI, Vuetify etc) all support this functionality with no fuss.