Merge pull request #9387 from 2betop/chore-select

fix: select 的 label 为对象时渲染异常
This commit is contained in:
hsm-lv 2024-01-10 13:05:15 +08:00 committed by GitHub
commit 592a8f0d8b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 51 additions and 23 deletions

View File

@ -1,4 +1,5 @@
import React from 'react';
import {string2regExp} from './string2regExp';
export function highlight(
text: string,
@ -10,7 +11,7 @@ export function highlight(
}
text = String(text);
const reg = new RegExp(input.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&'), 'ig');
const reg = string2regExp(input, false, true);
if (!reg.test(text)) {
return text;
}

View File

@ -27,6 +27,7 @@ export * from './image';
export * from './isPureVariable';
export * from './json-schema-2-amis-schema';
export * from './keyToPath';
export * from './labelToString';
export * from './makeSorter';
export * from './normalizeLink';
export * from './normalizeOptions';

View File

@ -0,0 +1,17 @@
import isPlainObject from 'lodash/isPlainObject';
export function labelToString(label: any): string {
if (typeof label === 'string') {
return label;
}
if (isPlainObject(label)) {
for (let key of ['__title', 'label', Object.keys(label)[0]]) {
if (typeof label[key] === 'string') {
return label[key];
}
}
}
return 'invalid label';
}

View File

@ -1,10 +1,14 @@
export function string2regExp(value: string, caseSensitive = false) {
export function string2regExp(
value: string,
caseSensitive = false,
globalSearch = false
) {
if (typeof value !== 'string') {
throw new TypeError('Expected a string');
}
return new RegExp(
value.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&').replace(/-/g, '\\x2d'),
!caseSensitive ? 'i' : ''
`${!caseSensitive ? 'i' : ''}${globalSearch ? 'g' : ''}`
);
}

View File

@ -8,6 +8,7 @@
import {
getOptionValue,
getOptionValueBindField,
labelToString,
uncontrollable
} from 'amis-core';
import React from 'react';
@ -829,6 +830,7 @@ export class Select extends React.Component<SelectProps, SelectState> {
...selection.slice(0, maxVisibleCount),
{[labelKey]: `+ ${selection.length - maxVisibleCount} ...`}
].map((item, index) => {
const label = labelToString(item[labelKey]);
if (index === maxVisibleCount) {
return (
<TooltipWrapper
@ -842,6 +844,7 @@ export class Select extends React.Component<SelectProps, SelectState> {
.slice(maxVisibleCount, selection.length)
.map((item, index) => {
const itemIndex = index + maxVisibleCount;
const label = labelToString(item[labelKey]);
return (
<div
key={itemIndex}
@ -855,7 +858,7 @@ export class Select extends React.Component<SelectProps, SelectState> {
<span className={cx('Select-valueLabel')}>
{renderValueLabel
? renderValueLabel(item)
: item[labelKey]}
: label}
</span>
<span
className={cx('Select-valueIcon', {
@ -882,7 +885,7 @@ export class Select extends React.Component<SelectProps, SelectState> {
} /** 避免点击查看浮窗时呼出下拉菜单 */
>
<span className={cx('Select-valueLabel')}>
{renderValueLabel ? renderValueLabel(item) : item[labelKey]}
{renderValueLabel ? renderValueLabel(item) : label}
</span>
</div>
</TooltipWrapper>
@ -893,7 +896,7 @@ export class Select extends React.Component<SelectProps, SelectState> {
<TooltipWrapper
container={popOverContainer}
placement={'top'}
tooltip={item[labelKey]}
tooltip={label}
trigger={'hover'}
key={index}
>
@ -904,7 +907,7 @@ export class Select extends React.Component<SelectProps, SelectState> {
})}
>
<span className={cx('Select-valueLabel')}>
{renderValueLabel ? renderValueLabel(item) : item[labelKey]}
{renderValueLabel ? renderValueLabel(item) : label}
</span>
<span
className={cx('Select-valueIcon', {
@ -921,6 +924,8 @@ export class Select extends React.Component<SelectProps, SelectState> {
}
return selection.map((item, index) => {
const label = labelToString(item[labelKey]);
if (!multiple) {
return (
<div
@ -930,18 +935,18 @@ export class Select extends React.Component<SelectProps, SelectState> {
})}
key={index}
>
{renderValueLabel ? renderValueLabel(item) : item[labelKey]}
{renderValueLabel ? renderValueLabel(item) : label}
</div>
);
}
return valuesNoWrap ? (
`${item[labelKey]}${index === selection.length - 1 ? '' : ' + '}`
`${label}${index === selection.length - 1 ? '' : ' + '}`
) : (
<TooltipWrapper
container={popOverContainer}
placement={'top'}
tooltip={item[labelKey]}
tooltip={label}
trigger={'hover'}
key={index}
>
@ -952,7 +957,7 @@ export class Select extends React.Component<SelectProps, SelectState> {
})}
>
<span className={cx('Select-valueLabel')}>
{renderValueLabel ? renderValueLabel(item) : item[labelKey]}
{renderValueLabel ? renderValueLabel(item) : label}
</span>
<span
className={cx('Select-valueIcon', {
@ -1050,6 +1055,9 @@ export class Select extends React.Component<SelectProps, SelectState> {
if (hideSelected && checked) {
return null;
}
let label = labelToString(item[labelField]);
return (
<div
{...getItemProps({
@ -1100,10 +1108,7 @@ export class Select extends React.Component<SelectProps, SelectState> {
})
)
) : multiple ? (
<div
title={item[labelField]}
className={cx('Select-option-checkbox')}
>
<div title={label} className={cx('Select-option-checkbox')}>
<Checkbox
checked={checked}
trueValue={item.value}
@ -1114,9 +1119,9 @@ export class Select extends React.Component<SelectProps, SelectState> {
size="sm"
>
{item.disabled
? item[labelField]
? label
: highlight(
item[labelField],
label,
inputValue as string,
cx('Select-option-hl')
)}
@ -1127,14 +1132,12 @@ export class Select extends React.Component<SelectProps, SelectState> {
) : (
<span
className={cx('Select-option-content')}
title={
typeof item[labelField] === 'string' ? item[labelField] : ''
}
title={typeof label === 'string' ? label : ''}
>
{item.disabled
? item[labelField]
? label
: highlight(
item[labelField],
label,
inputValue as string,
cx('Select-option-hl')
)}
@ -1326,7 +1329,9 @@ export class Select extends React.Component<SelectProps, SelectState> {
multiple ? noop : this.handleChange
}
onStateChange={this.handleStateChange}
itemToString={item => (item ? `${item[labelField]}` : '')}
itemToString={item =>
item ? `${labelToString(item[labelField])}` : ''
}
>
{(options: ControllerStateAndHelpers<any>) => {
const {isOpen} = options;