Rendering Primitives
Turn a Core primitive into Svelte components with createParts.
This page renders the rating from Compose Behaviors. Start with that guide's complete rating.ts: 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:
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:
<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 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 when you want to change their markup.
Add Logic to a Part
Keep createParts when mapping slots to elements is enough. Custom Parts uses the same rating to show how usePrimitive and usePart let you write your own root or child part.