Skip to content

Commit 7af2f3c

Browse files
authored
handle empty attribute values in SearchList (#452)
1 parent 163b0f8 commit 7af2f3c

File tree

1 file changed

+54
-42
lines changed

1 file changed

+54
-42
lines changed

packages/core-data/src/components/SearchListItem.js

Lines changed: 54 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// @flow
22

3-
import React, { type Element } from 'react';
3+
import React, { type Element, useMemo } from 'react';
44
import clsx from 'clsx';
55
import Icon from './Icon';
66
import { type Attribute } from '../types/SearchList';
@@ -61,46 +61,58 @@ const ItemWrapper = (props: ItemWrapperProps) => {
6161
return props.children;
6262
};
6363

64-
const SearchListItem = (props: SearchListItemProps) => (
65-
<li
66-
className={clsx(
67-
{ 'bg-neutral-200': props.isHighlight },
68-
{ 'hover:bg-neutral-200': !!props.onClick }
69-
)}
70-
>
71-
<ItemWrapper {...props}>
72-
<div
73-
className='py-3 px-6'
74-
onPointerEnter={props.onPointerEnter
75-
? () => props.onPointerEnter(props.item)
76-
: undefined}
77-
onPointerLeave={props.onPointerLeave
78-
? () => props.onPointerLeave(props.item)
79-
: undefined}
80-
>
81-
<p className='font-bold text-neutral-800'>{props.title}</p>
82-
{props.attributes && props.attributes.length > 0 && (
83-
<ul className='list-none'>
84-
{props.attributes.slice(0, 3).map((att) => (
85-
<li
86-
className='text-sm text-neutral-800 flex gap-2 items-center list-none pl-5 pt-1'
87-
key={att.name}
88-
>
89-
<Icon
90-
className='min-w-[13px]'
91-
name={att.icon || 'bullet'}
92-
size={13}
93-
/>
94-
{att.render
95-
? att.render(props.item)
96-
: props.item[att.name]}
97-
</li>
98-
))}
99-
</ul>
100-
)}
101-
</div>
102-
</ItemWrapper>
103-
</li>
104-
);
64+
const SearchListItem = (props: SearchListItemProps) => {
65+
const attributeValues = useMemo(() => props.attributes.slice(0, 3).map((attribute) => {
66+
if (attribute.render) {
67+
return attribute.render(props.item);
68+
}
69+
70+
return props.item[attribute.name];
71+
}), [props.attributes, props.item]);
72+
73+
return (
74+
<li
75+
className={clsx(
76+
{ 'bg-neutral-200': props.isHighlight },
77+
{ 'hover:bg-neutral-200': !!props.onClick }
78+
)}
79+
>
80+
<ItemWrapper {...props}>
81+
<div
82+
className='py-3 px-6'
83+
onPointerEnter={props.onPointerEnter
84+
? () => props.onPointerEnter(props.item)
85+
: undefined}
86+
onPointerLeave={props.onPointerLeave
87+
? () => props.onPointerLeave(props.item)
88+
: undefined}
89+
>
90+
<p className='font-bold text-neutral-800'>{props.title}</p>
91+
{props.attributes && attributeValues.some(Boolean) && (
92+
<ul className='list-none'>
93+
{props.attributes.slice(0, 3).map((att, idx) => (
94+
<>
95+
{!!attributeValues[idx] && (
96+
<li
97+
className='text-sm text-neutral-800 flex gap-2 items-center list-none pl-5 pt-1'
98+
key={att.name}
99+
>
100+
<Icon
101+
className='min-w-[13px]'
102+
name={att.icon || 'bullet'}
103+
size={13}
104+
/>
105+
{attributeValues[idx]}
106+
</li>
107+
)}
108+
</>
109+
))}
110+
</ul>
111+
)}
112+
</div>
113+
</ItemWrapper>
114+
</li>
115+
);
116+
};
105117

106118
export default SearchListItem;

0 commit comments

Comments
 (0)