Skip to content

@vibe-labs/design-components-core

Shared component primitives (field wrapper, close button) for the Vibe Design System.

Installation

bash
npm install @vibe-labs/design-components-core
css
@import "@vibe-labs/design-components-core";
ts
import { CloseBtnSizes } from "@vibe-labs/design-components-core/types";
import type { FieldStyleProps, CloseBtnStyleProps } from "@vibe-labs/design-components-core/types";

Contents

Tokens

CSS custom properties defined in @layer vibe.tokens (file: core.css).

Field Wrapper

TokenDefaultDescription
--field-gap--space-1Gap between label, control, and help/error
--field-label-font-size--text-smLabel font size
--field-label-font-weight--font-semiboldLabel font weight
--field-label-color--text-primaryLabel color
--field-help-font-size--text-xsHelp text font size
--field-help-color--text-mutedHelp text color
--field-error-font-size--text-xsError/success message font size
--field-required-color--color-dangerRequired indicator color

Close Button

TokenDefaultDescription
--close-btn-color--text-mutedDefault icon color
--close-btn-hover-color--text-primaryHover icon color
--close-btn-hover-bg--surface-hover-overlayHover background
--close-btn-radius--radius-smBorder radius
--close-btn-size-sm1.25remSmall size
--close-btn-size-md1.75remMedium size (default)
--close-btn-size-lg2remLarge size

Generated Styles

Component classes generated into @layer vibe.components (file: core.g.css).

Field Wrapper

ClassDescription
.fieldVertical flex column — label → control → help/error
.field-labelStyled label text
.field-requiredDanger-colored required indicator (*)
.field-helpMuted help text below control
.field-errorError message (danger color)
.field-successSuccess message (success color)

Modifier: .field[data-horizontal] — switches to row layout with fixed-width label (8rem min).

Close Button

ClassDescription
.close-btnInline-flex centered button with hover/focus states

Sizes: data-size="sm" · data-size="md" (default) · data-size="lg"

Focus-visible ring is applied via box-shadow.

TypeScript Types

ts
CloseBtnSizes // ["sm", "md", "lg"]
type CloseBtnSize

interface FieldStyleProps { horizontal?: boolean }
interface FieldLabelStyleProps {}
interface FieldRequiredStyleProps {}
interface FieldHelpStyleProps {}
interface FieldErrorStyleProps {}
interface FieldSuccessStyleProps {}
interface CloseBtnStyleProps { size?: CloseBtnSize }

Dist Structure

FileDescription
index.cssBarrel — imports tokens + generated styles
core.cssToken definitions
core.g.cssGenerated component styles
index.js / index.d.tsTypeScript types + runtime constants

Dependencies

Requires tokens from @vibe-labs/design (typography, spacing, colors, surfaces, transitions, elevation).

Build

bash
npm run build

Usage Guide

Import

css
@import "@vibe-labs/design-components-core";
ts
import type { FieldStyleProps, CloseBtnStyleProps } from "@vibe-labs/design-components-core/types";

Variants

Field Wrapper

The field wrapper uses data-horizontal for layout switching. No data-variant — the field is structural only.

Close Button

Close button uses data-size for three size options: sm, md (default), lg.

Examples

Basic vertical field

html
<!-- Standard vertical field with label, input, and help text -->
<div class="field">
  <label class="field-label">
    Email address
    <span class="field-required">*</span>
  </label>
  <input type="email" class="input" placeholder="you@example.com" />
  <span class="field-help">We'll never share your email.</span>
</div>

Field with error state

html
<!-- Field displaying a validation error -->
<div class="field">
  <label class="field-label">Username</label>
  <input type="text" class="input" data-state="error" value="x" />
  <span class="field-error">Username must be at least 3 characters.</span>
</div>

Field with success state

html
<!-- Field displaying a success confirmation -->
<div class="field">
  <label class="field-label">Password</label>
  <input type="password" class="input" data-state="success" />
  <span class="field-success">Password meets requirements.</span>
</div>

Horizontal layout

html
<!-- Horizontal field: label sits to the left of the control -->
<div class="field" data-horizontal>
  <label class="field-label">Display name</label>
  <input type="text" class="input" />
</div>

Close button sizes

html
<!-- Small close button (e.g. inside a badge) -->
<button class="close-btn" data-size="sm" aria-label="Remove">
  <svg><!-- × icon --></svg>
</button>

<!-- Default medium close button (e.g. inside a toast) -->
<button class="close-btn" aria-label="Dismiss">
  <svg><!-- × icon --></svg>
</button>

<!-- Large close button (e.g. inside a modal header) -->
<button class="close-btn" data-size="lg" aria-label="Close dialog">
  <svg><!-- × icon --></svg>
</button>

With Vue

Use @vibe-labs/design-vue-core for <SbField>, <SbFieldLabel>, <SbFieldHelp>, <SbFieldError>, and <SbCloseBtn> components that accept the typed props from FieldStyleProps and CloseBtnStyleProps.

Vibe