Appearance
@vibe-labs/design — Build Selectors Reference
Shared selector helpers used by all design-components-* generate scripts. Located at Platform/Web/packages/design/.build/selectors.ts.
Mode
Controlled via CLI flag --mode attr|flat. Defaults to attr.
attr— data-attribute selectors:.btn[data-variant="primary"],.table[data-striped]flat— flat class selectors:.btn-primary,.table-striped
Functions
base(name: string): string
Returns the base class selector for a component element.
ts
base("table"); // → ".table"
base("table-header"); // → ".table-header"
base("tab-icon"); // → ".tab-icon"Use for: any element that is always present regardless of variant/state.
variant(base: string, axis: string, value: string): string
Returns a selector for a key-value data-attribute (enumerated option).
ts
variant("table", "variant", "elevated"); // attr → .table[data-variant="elevated"]
// flat → .table-elevated
variant("table", "size", "sm"); // attr → .table[data-size="sm"]
// flat → .table-sm
variant("tabs", "variant", "pill"); // attr → .tabs[data-variant="pill"]
// flat → .tabs-pillUse for: props with a fixed set of named values — variant, size, align, position, etc.
flag(base: string, name: string): string
Returns a selector for a boolean data-attribute (presence/absence).
ts
flag("table", "striped"); // attr → .table[data-striped]
// flat → .table-striped
flag("table", "hoverable"); // attr → .table[data-hoverable]
// flat → .table-hoverable
flag("tabs", "scrollable"); // attr → .tabs[data-scrollable]
// flat → .tabs-scrollableUse for: boolean flags — striped, hoverable, interactive, full, scrollable, fixed-header, etc.
Decision Guide
| Scenario | Function | Example |
|---|---|---|
| Element class name | base() | .table-row, .tab-panel |
| Enum prop with named values | variant() | data-size="lg", data-variant="ghost" |
| Boolean on/off flag | flag() | data-striped, data-full |
| ARIA state (not from selectors) | raw string | [aria-selected="true"], [data-sorted="asc"] |
⚠️ flag() takes 2 args (base, name). variant() takes 3 args (base, axis, value). Passing 3 args to flag() silently ignores the third — use variant() for key-value pairs.
Source
ts
type __SelectorMode__ = "attr" | "flat";
const mode: __SelectorMode__ = process.argv.includes("--mode")
? (process.argv[process.argv.indexOf("--mode") + 1] as __SelectorMode__)
: "attr";
export function variant(base: string, axis: string, value: string): string {
return mode === "flat" ? `.${base}-${value}` : `.${base}[data-${axis}="${value}"]`;
}
export function flag(base: string, name: string): string {
return mode === "flat" ? `.${base}-${name}` : `.${base}[data-${name}]`;
}
export function base(name: string): string {
return `.${name}`;
}