import { Meta } from "@storybook/addon-docs";

<Meta
    title="Features/Slots"
    id="slots"
/>

# Slots

Slots allows a component to support multiple layouts in a declarative way by defining a template of named placeholders for consumers.

## Types of slots

In Orbit, component placeholders are fulfilled through his children and slots are defined [implicitly](#implicit-slots) or [explicitly](#explicit-slots) on the child component.

In the following example, the `<Text>` component *implicitly* fulfill the `text` slot of the button and the `<LightbulbMajorIcon>` component *explicitly* fulfill the `end-icon` slot of the button.

```jsx
<Button variant="secondary">
    <Text>Cutoff</Text>
    <LightbulbMajorIcon slot="end-icon" />
</Button>
```

To identify which slots placeholders are available for a component, refer to the [API section of a component](?path=/docs/button--default-story#button-1).

### Implicit slots

Some of Orbit components which are considered *slotables* are defined to automatically fullfill a specific placeholder of a component when available. If a match happens, we say the fullfillment is *implicit*.

For example, an `<Icon>` component will implicitly fulfill the `icon` slot of a `<Button>` when defined as his child.

```jsx
<Button variant="secondary">
    <LightbulbMajorIcon />
    <Text>Cutoff</Text>
</Button>
```

An implicit slot can be defined on a custom component by using the `slot` function.

```jsx
import { slot } from "@sharegate/orbit-ui";

export const MyComponent = slot("name-of-the-slot-to-fulfill-by-default", () => (
    <Div>A custom component</Div>
));
```

### Explicit slots

Sometimes, we want to force a component into a specific placeholder of a component. To do so, an *explicit* slot can be specified on a child component with the `slot` prop. *Explicit slots will have precedence over implicit slots*.

```jsx
<Button variant="secondary">
    <Text>Cutoff</Text>
    <LightbulbMajorIcon slot="end-icon" />
</Button>
```

For native HTML elements, instead of specifying an explicit slot directly on the native element, we recommend using [Orbit HTML elements](?path=/docs/html-anchor--example).

```jsx
<Card>
    <H1>SpaceX delays launch of South Korean military satellite</H1>
    <Div slot="content">SpaceX postponed the upcoming launch of a South Korean military satellite Monday (July 13), due to hardware issues with the Falcon 9 rocket.</Div>
    <Div slot="footer">Copyright @2021</Div>
</Card>
```

## Other resources

For more information about the slots concepts, have a look at web components slots on [MDN](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_templates_and_slots#adding_flexibility_with_slots).

