Skip to content

@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-pill

Use 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-scrollable

Use for: boolean flags — striped, hoverable, interactive, full, scrollable, fixed-header, etc.


Decision Guide

ScenarioFunctionExample
Element class namebase().table-row, .tab-panel
Enum prop with named valuesvariant()data-size="lg", data-variant="ghost"
Boolean on/off flagflag()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}`;
}