# Rendering Primitives

Turn a Core primitive into Svelte components with createParts.

This page renders the rating from [Compose Behaviors](/docs/core/compose-behaviors). Start with that guide's [complete `rating.ts`](/docs/core/compose-behaviors#complete-primitive): it already handles selection, arrow keys, and focus. Here we'll connect its `root` and `star` slots to Svelte.

## Create the Parts

`createParts` maps slots to elements. Save this beside `rating.ts`:

```ts title="rating-parts.ts"
import { createParts } from "@ui-sdk/svelte/primitive"
import { rating } from "./rating"

const { Root: RatingRoot, Star: RatingStar } = createParts(rating, {
  root: "div",
  star: "button",
})

export { RatingRoot, RatingStar }
```

`Root` creates the instance and shares it with the parts inside. Each mapped slot becomes a component. Slot names become Pascal case: `star` becomes `Star`, and `tab-icon` would become `TabIcon`.

If you leave out the `root` tag, `Root` still shares the instance but renders only its children.

## Render the Rating

The root accepts the primitive's options and the element's props. Each star receives its slot value and a name a screen reader can announce:

```svelte
<script lang="ts">
  import { RatingRoot, RatingStar } from "./rating-parts"
</script>

<RatingRoot defaultValue={4} aria-label="Rating" class="flex gap-1">
  {#each Array.from({ length: 5 }, (_, index) => index + 1) as star (star)}
    <RatingStar
      value={String(star)}
      aria-label={`${star} ${star === 1 ? "star" : "stars"}`}
      class="opacity-40 data-filled:opacity-100">★</RatingStar
    >
  {/each}
</RatingRoot>
```

The primitive supplies `data-filled`; these classes make the filled stars easier to see. [Styling and Animation](/docs/svelte/styling-and-animation) covers other ways to style parts.

Generated parts also support the same `children` and `render` snippets as the components in the catalog. Use [Parts and Composition](/docs/svelte/parts-and-composition) when you want to change their markup.

## Add Logic to a Part

Keep `createParts` when mapping slots to elements is enough. [Custom Parts](/docs/svelte/custom-parts) uses the same rating to show how `usePrimitive` and `usePart` let you write your own root or child part.
