Facetcomponents

Label

A form label — one recipe, no variants, and the smallest component in the registry.

Terminal window
npx facet-rbxts add label

Copies ui/label.tsx, plus lib/utils.ts. Needs @facet-ui/react-variants and @lattice-ui/react-runtime.

import { Label } from "../shared/ui/label";
<Label Text="Display name" />

A second text colour is a second element, not a className on this one — a class written here is lowered before Label ever sees it, and then overwritten by the component’s own recipe. See Overriding from the call site.

The recipe, and a second text colour stated on its own element.

Renders a TextLabel. Unknown props forward onto it and are type-checked against it, so a prop TextLabel does not accept is a compile error.

Props

PropTypeDescription
TextstringThe label. Drawn as this instance's own Text — unlike Button, there is nothing to compose around, so there is no TextSlot.
classNameClassNameThreaded into the recipe's className slot inside the component. A class written at a Vela-compiled call site never reaches it — see Overriding from the call site.

Everything else is forwarded onto the TextLabel.

The recipe

export const labelVariants = fv("text-foreground text-sm font-medium");

That is the whole thing — no variant axes. fv() with no config is still worth using over a bare string: it gives you the className slot with the right ordering, and it is the seam a variant axis grows into if you add one.

font-medium is not optional. Vela leaves FontFace untouched when no font-* token appears, and Roblox’s untouched default is LegacyArial — a different typeface at a visibly different size from the SourceSansPro everything else resolves to. Every text recipe in the registry declares a weight for that reason. See Text and labels.

A leaf, so it draws its own text

Button and Badge delegate to TextSlot because they compose — a label beside an icon, a child element instead of a string. Label has nothing to compose around, so it draws Text directly:

<textlabel
className={cn(labelVariants({ className: props.className }))}
Text={props.Text ?? ""}
{...NEUTRAL_PROPS}
AutomaticSize={Enum.AutomaticSize.XY}
{...passthrough}
/>

AutomaticSize is set as an instance prop rather than through a class, and it sits before the passthrough spread so a consumer can override it. Without a resolved size, a label collapses the automatic sizing of whatever contains it — see Component conventions.