Skip to content

Commit a709176

Browse files
committed
Default keys for multi-text children (#293)
1 parent 3882a01 commit a709176

1 file changed

Lines changed: 21 additions & 9 deletions

File tree

packages/components/src/spectrum/picker/PickerItemContent.tsx

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,29 @@ export function PickerItemContent({
2727
// Boolean values need to be stringified to render
2828
content = String(content);
2929
} else if (Array.isArray(content)) {
30-
// For cases where there are multiple `Text` children, add css class to
31-
// handle overflow
32-
content = content.map(item =>
30+
// For cases where there are multiple `Text` children, add a css class to
31+
// handle overflow. The primary use case for multiple text nodes is when a
32+
// description is provided for an item. e.g.
33+
// <Item textValue="Some Text">
34+
// <SomeIcon />
35+
// <Text>Some Label</Text>
36+
// <Text slot="description">Some Description</Text>
37+
// </Item>
38+
content = content.map((item, i) =>
3339
isElementOfType(item, Text)
34-
? // Cloning elements has the side effect of resetting React's internal
35-
// `_store.validated` value to `false on each item. This causes them
36-
// to be re-validated when they are rendered. Since they are inside of
37-
// an array, React will show devtools warnings if they are missing `key`
38-
// props.
39-
cloneElement(item, {
40+
? cloneElement(item, {
4041
...item.props,
42+
// `cloneElement` has the side effect of resetting React's internal
43+
// `_store.validated` value to `false on the item. This causes it
44+
// to be re-validated as a child in an array when is is rendered,
45+
// even if the item was originally provided as an inline child.
46+
// Since React expects array children to have explicit keys, this
47+
// will show devtools warnings for items that wouldn't usually
48+
// require explicit keys. Since we are only cloning `Text` nodes, it
49+
// should be reasonable to fallback to a key matching the stringified
50+
// content. The index suffix is an extra precation for when 2 <Text>
51+
// nodes have the same value.
52+
key: item.key ?? `${item.props.children}_${i}`,
4153
UNSAFE_className: cl(
4254
item.props.UNSAFE_className,
4355
stylesCommon.spectrumEllipsis

0 commit comments

Comments
 (0)