Skip to content

Commit

Permalink
refactor: apply review suggestions, extend tests
Browse files Browse the repository at this point in the history
  • Loading branch information
web-padawan committed Dec 12, 2023
1 parent b1b6891 commit a4c1a6d
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 15 deletions.
19 changes: 5 additions & 14 deletions src/Select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,29 +29,20 @@ function Select(props: SelectProps, ref: ForwardedRef<SelectElement>): ReactElem
const children = Children.toArray(props.children as ReactNode[]);

// Components with slot attribute should stay in light DOM.
const slotted = children.filter((child: any) => {
return 'props' in child && child.props.slot;
const slotted = children.filter((child) => {
return typeof child === 'object' && 'props' in child && child.props.slot;
});

// Component without slot attribute should go to the overlay.
let overlayChildren: ReactNode[] | undefined;

children.forEach((child) => {
if (!slotted.includes(child)) {
if (!overlayChildren) {
overlayChildren = [];
}
overlayChildren.push(child);
}
});
const overlayChildren = children.filter((child) => !slotted.includes(child));

// React.Children.toArray() doesn't allow functions, so we convert manually.
const renderFn = (Array.isArray(props.children) ? props.children : [props.children]).find(
(child: any) => typeof child === 'function',
(child) => typeof child === 'function',
);

const innerRef = useRef<SelectElement>(null);
const [portals, renderer] = useSimpleOrChildrenRenderer(props.renderer, renderFn || overlayChildren);
const [portals, renderer] = useSimpleOrChildrenRenderer(props.renderer, renderFn || (overlayChildren.length ? overlayChildren : undefined));
const finalRef = useMergedRefs(innerRef, ref);

useEffect(() => {
Expand Down
39 changes: 38 additions & 1 deletion test/Select.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,10 @@ describe('Select', () => {

await expect(findByQuerySelector('vaadin-select-value-button')).to.eventually.have.text('Bar');
});
});

it('should correctly render the element with prefix slot', async () => {
describe('slot', () => {
it('should render the element with slot if renderer prop is set', async () => {
render(
<Select renderer={Renderer}>
<div slot="prefix">Value:</div>
Expand All @@ -105,5 +107,40 @@ describe('Select', () => {

await expect(findByQuerySelector('div[slot="prefix"]')).to.eventually.have.text('Value:');
});

it('should render the element with slot if items prop is set', async () => {
render(
<Select items={items}>
<div slot="prefix">Value:</div>
</Select>,
);

await expect(findByQuerySelector('div[slot="prefix"]')).to.eventually.have.text('Value:');
});

it('should render the element with slot if children render function is set', async () => {
render(
<Select>
{Renderer}
<div slot="prefix">Value:</div>
</Select>,
);

await expect(findByQuerySelector('div[slot="prefix"]')).to.eventually.have.text('Value:');
});

it('should render the element with slot if children component is set', async () => {
render(
<Select>
<ListBox>
<Item value="foo">Foo</Item>
<Item value="bar">Bar</Item>
</ListBox>
<div slot="prefix">Value:</div>
</Select>,
);

await expect(findByQuerySelector('div[slot="prefix"]')).to.eventually.have.text('Value:');
});
});
});

0 comments on commit a4c1a6d

Please sign in to comment.