Skip to main content

Slot

A component that merges given props into its immediate child component and renders it.

Slot implements the Composition pattern that combines a parent component's features with its child. This allows you to:

  • Pass the parent component's props, ref, event handlers, etc. to the child component
  • Add new functionality without modifying the child component's implementation
  • Reduce coupling between components and improve reusability

For example, in components like InView or AspectRatio, using the asChild prop lets you inject functionality directly into the child without a wrapper element.

Slot has the following characteristics.

  1. Only a single child element is accepted.
typescript
// Allowed
<Slot>
<div>Contents</div>
</Slot>

// Allowed
<Slot>
<div>
<div>Contents1</div>
<div>Contents2</div>
</div>
</Slot>
typescript
// Not allowed
<Slot>
<div>Contents1</div>
<div>Contents2</div>
</Slot>
  1. If a component is passed as a child, it must support forwardRef and spread props. Otherwise the functionality will not work correctly.
typescript
const MyButton = React.forwardRef((props, forwardedRef) => (
<button {...props} ref={forwardedRef} />
));

<Slot>
<MyButton>Button</MyButton>
</Slot>

Code

🔗 실제 구현 코드 확인


Interface

typescript
const Slot: React.ForwardRefExoticComponent<
React.HTMLAttributes<HTMLElement> & {
children?: React.ReactNode;
} & React.RefAttributes<HTMLElement>
>;
typescript
const Slottable: ({ children }: React.PropsWithChildren) => JSX.Element;

Usage

Basic Usage

typescript
import { Slot } from '@modern-kit/react'

const Button = ({
asChild,
...props
}: PropsWithChildren<{ asChild?: boolean } & ComponentProps<'button'>>) => {
const Comp = asChild ? Slot : 'button';

return <Comp {...props} />;
};

With Slottable Usage

typescript
const SlottableButton = ({
asChild,
leftElement,
rightElement,
...props
}: PropsWithChildren<
{
asChild?: boolean;
leftElement: ReactElement;
rightElement: ReactElement;
} & ComponentProps<'button'>
>) => {
const Comp = asChild ? Slot : 'button';

return (
<Comp {...props}>
{leftElement}
<Slottable>{props.children}</Slottable>
{rightElement}
</Comp>
);
};

Example

Basic Usage

typescript
// Basic Usage
<Button onClick={() => console.log('click')}>Button</Button>

AsChild Usage

typescript
// AsChild Usage
<Button asChild onClick={() => console.log('click')}>
<div>asChild Button</div>
</Button>
asChild Button

Slottable Usage

typescript
<SlottableButton leftElement={<span>left</span>} rightElement={<span>right</span>}>
<span> Slottable Button </span>
</SlottableButton>