Skip to main content

Primitives

Fluid Primitives exposes headless primitives that you can use to build your own components. These primitives are built on top of Zag.js state machines and provide the necessary behavior and accessibility features.

They are exposed in the primitives namespace.

Anatomy

For example the Tooltip anatomy looks like this:

<primitives:tooltip.root>
    <primitives:tooltip.trigger />
    <primitives:tooltip.positioner>
        <primitives:tooltip.content>
            <primitives:tooltip.arrow />
        </primitives:tooltip.content>
    </primitives:tooltip.positioner>
</primitives:tooltip.root>

You could use them directly in your templates and add your classes and styles. But they are mainly meant to be used as building blocks for your own components.

Building Components with Primitives

Its recommended to create components for each primitive part, so you can easily customize the styling and behavior of your design system in one place. See the File Structure documentation for more details.

In this case we could simplify it a little bit and wrap the positioner, content and arrow parts into a single content part. Inside there you can then also use the ui:portal ViewHelper if you want. Take a look at the Tooltip component from the docs sitepackage.

Inside the Root.html file of your component you can then use the ui:useProps ViewHelper to import all props from the primitive and pass them to the primitive root part with spreadProps="{true}".

<ui:useProps name="primitives:tooltip.root" />

<primitives:tooltip.root spreadProps="{true}">
    <f:slot />
</primitives:tooltip.root>

<vite:asset entry="EXT:docs/Resources/Private/Components/ui/Tooltip/source/Tooltip.entry.ts" />

Note that we also load the component's JavaScript entry file with the Vite Asset Collector ViewHelper here instead of in our main JavaScript file so its only included if we use the component.

Now we can simply use our ui:tooltip component like this:

<ui:tooltip.root>
    <ui:tooltip.trigger>Hover me</ui:tooltip.trigger>
    <ui:tooltip.content>This is the tooltip content.</ui:tooltip.content>
</ui:tooltip.root>