Skip to content

Commit

Permalink
fix: title in option not work (#833)
Browse files Browse the repository at this point in the history
* test: fix title missing

* test: add test case

* chore: clean lint rule
  • Loading branch information
zombieJ committed Sep 17, 2022
1 parent 590e54d commit 4853ba4
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 9 deletions.
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@ module.exports = {
'react/sort-comp': 0,
'jsx-a11y/interactive-supports-focus': 0,
'jsx-a11y/no-autofocus': 0,
'react/no-unknown-property': 0,
},
};
1 change: 1 addition & 0 deletions src/BaseSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ export interface DisplayValueType {
key?: React.Key;
value?: RawValueType;
label?: React.ReactNode;
title?: string | number;
disabled?: boolean;
}

Expand Down
3 changes: 3 additions & 0 deletions src/Select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ const Select = React.forwardRef(
let rawLabel: React.ReactNode;
let rawKey: React.Key;
let rawDisabled: boolean | undefined;
let rawTitle: string;

// Fill label & value
if (isRawValue(val)) {
Expand All @@ -264,6 +265,7 @@ const Select = React.forwardRef(
rawLabel = option?.[optionLabelProp || mergedFieldNames.label];
if (rawKey === undefined) rawKey = option?.key ?? rawValue;
rawDisabled = option?.disabled;
rawTitle = option?.title;

// Warning if label not same as provided
if (process.env.NODE_ENV !== 'production' && !optionLabelProp) {
Expand All @@ -279,6 +281,7 @@ const Select = React.forwardRef(
value: rawValue,
key: rawKey,
disabled: rawDisabled,
title: rawTitle,
};
});
},
Expand Down
9 changes: 4 additions & 5 deletions src/Selector/MultipleSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import type { InnerSelectorProps } from '.';
import Input from './Input';
import useLayoutEffect from '../hooks/useLayoutEffect';
import type { DisplayValueType, RenderNode, CustomTagProps, RawValueType } from '../BaseSelect';
import { getTitle } from '../utils/commonUtil';

function itemKey(value: DisplayValueType) {
return value.key ?? value.value;
Expand Down Expand Up @@ -89,7 +90,7 @@ const SelectSelector: React.FC<SelectorProps> = (props) => {
// ===================== Render ======================
// >>> Render Selector Node. Includes Item & Rest
function defaultRenderSelector(
title: React.ReactNode,
item: DisplayValueType,
content: React.ReactNode,
itemDisabled: boolean,
closable?: boolean,
Expand All @@ -100,9 +101,7 @@ const SelectSelector: React.FC<SelectorProps> = (props) => {
className={classNames(`${selectionPrefixCls}-item`, {
[`${selectionPrefixCls}-item-disabled`]: itemDisabled,
})}
title={
typeof title === 'string' || typeof title === 'number' ? title.toString() : undefined
}
title={getTitle(item)}
>
<span className={`${selectionPrefixCls}-item-content`}>{content}</span>
{closable && (
Expand Down Expand Up @@ -167,7 +166,7 @@ const SelectSelector: React.FC<SelectorProps> = (props) => {

return typeof tagRender === 'function'
? customizeRenderSelector(value, displayLabel, itemDisabled, closable, onClose)
: defaultRenderSelector(label, displayLabel, itemDisabled, closable, onClose);
: defaultRenderSelector(valueItem, displayLabel, itemDisabled, closable, onClose);
}

function renderRest(omittedValues: DisplayValueType[]) {
Expand Down
7 changes: 3 additions & 4 deletions src/Selector/SingleSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as React from 'react';
import pickAttrs from 'rc-util/lib/pickAttrs';
import Input from './Input';
import type { InnerSelectorProps } from '.';
import { getTitle } from '../utils/commonUtil';

interface SelectorProps extends InnerSelectorProps {
inputElement: React.ReactElement;
Expand Down Expand Up @@ -57,10 +58,8 @@ const SingleSelector: React.FC<SelectorProps> = (props) => {
// Not show text when closed expect combobox mode
const hasTextInput = mode !== 'combobox' && !open && !showSearch ? false : !!inputValue;

const title =
item && (typeof item.label === 'string' || typeof item.label === 'number')
? item.label.toString()
: undefined;
// Get title
const title = getTitle(item);

const renderPlaceholder = () => {
if (item) {
Expand Down
19 changes: 19 additions & 0 deletions src/utils/commonUtil.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import type { DisplayValueType } from '../BaseSelect';

export function toArray<T>(value: T | T[]): T[] {
if (Array.isArray(value)) {
return value;
Expand All @@ -14,3 +16,20 @@ export const isBrowserClient = process.env.NODE_ENV !== 'test' && isClient;
export function hasValue(value) {
return value !== undefined && value !== null;
}

function isTitleType(title: any) {
return ['string', 'number'].includes(typeof title);
}

export function getTitle(item: DisplayValueType): string {
let title: string = undefined;
if (item) {
if (isTitleType(item.title)) {
title = item.title.toString();
} else if (isTitleType(item.label)) {
title = item.label.toString();
}
}

return title;
}
29 changes: 29 additions & 0 deletions tests/Select.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1914,4 +1914,33 @@ describe('Select.Basic', () => {
expect(wrapper.find('div.rc-select-item').prop('data-test')).toEqual('good');
expect(wrapper.find('div.rc-select-item').prop('aria-label')).toEqual('well');
});

// https://github.com/ant-design/ant-design/issues/37591
describe('title attr', () => {
it('single', () => {
const wrapper = mount(
<Select value="b" options={[{ label: 'bamboo', title: 'TitleBamboo', value: 'b' }]} />,
);

expect(wrapper.find('.rc-select-selection-item').prop('title')).toEqual('TitleBamboo');
});

it('multiple', () => {
const wrapper = mount(
<Select
mode="multiple"
value={['b', 'l']}
options={[
{ label: 'bamboo', title: 'TitleBamboo', value: 'b' },
{ label: 'little', value: 'l' },
]}
/>,
);

expect(wrapper.find('.rc-select-selection-item').first().prop('title')).toEqual(
'TitleBamboo',
);
expect(wrapper.find('.rc-select-selection-item').last().prop('title')).toEqual('little');
});
});
});

1 comment on commit 4853ba4

@vercel
Copy link

@vercel vercel bot commented on 4853ba4 Sep 17, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

select – ./

select.vercel.app
select-git-master-react-component.vercel.app
select-react-component.vercel.app

Please sign in to comment.