Skip to content

@vibe-labs/design-components-inputs

Text input, textarea, checkbox, and radio component tokens, styles, and TypeScript types for the Vibe Design System.

Installation

bash
npm install @vibe-labs/design-components-inputs
css
@import "@vibe-labs/design-components-inputs";
ts
import { InputSizes, CheckboxSizes, RadioSizes } from "@vibe-labs/design-components-inputs/types";
import type { InputStyleProps, CheckboxStyleProps, RadioStyleProps } from "@vibe-labs/design-components-inputs/types";

Contents

Tokens

Component-specific tokens defined in @layer vibe.tokens (file: input.css). Core sizing tokens (--input-height-*, --input-border, --input-disabled-opacity) are owned by @vibe-labs/design-forms. Field wrapper tokens (--field-*) are owned by @vibe-labs/design-components-core.

Text Input / Textarea

TokenDefaultDescription
--input-bg--surface-baseBackground
--input-color--text-primaryText color
--input-radius--radius-mdBorder radius
--input-font-size-sm--text-smSmall font size
--input-font-size-md--text-smMedium font size
--input-font-size-lg--text-baseLarge font size
--input-px-sm--space-2Small horizontal padding
--input-px-md--space-3Medium horizontal padding
--input-px-lg--space-3Large horizontal padding
--input-placeholder-color--text-mutedPlaceholder color
--input-focus-border--color-accentFocus border color
--input-error-border--color-dangerError state border
--input-error-color--color-dangerError state color
--input-success-border--color-successSuccess state border
--input-success-color--color-successSuccess state color
--textarea-min-height5remMinimum textarea height

Checkbox

TokenDefaultDescription
--checkbox-size-sm0.875remSmall box size
--checkbox-size-md1remMedium box size
--checkbox-size-lg1.25remLarge box size
--checkbox-radius--radius-xsCorner radius
--checkbox-bg--surface-baseUnchecked background
--checkbox-border-color--border-strongUnchecked border
--checkbox-checked-bg--color-accentChecked background
--checkbox-checked-border--color-accentChecked border
--checkbox-check-color--color-accent-contrastCheckmark color

Radio

TokenDefaultDescription
--radio-size-sm0.875remSmall circle size
--radio-size-md1remMedium circle size
--radio-size-lg1.25remLarge circle size
--radio-bg--surface-baseUnchecked background
--radio-border-color--border-strongUnchecked border
--radio-checked-bg--color-accentChecked background
--radio-checked-border--color-accentChecked border
--radio-dot-color--color-accent-contrastInner dot color
--radio-dot-scale0.4Inner dot size relative to circle

Generated Styles

Text Input (input.g.css)

  • .input — full-width block input with hover/focus/disabled/readonly states
  • Sizes: data-size="sm|md|lg" (default: md)
  • Validation: data-state="error|success" — changes border and focus ring color
  • Slots: .input-wrap container with .input-leading and .input-trailing positions; padding auto-adjusts via :has()
  • Textarea: .textarea with data-no-resize and data-auto-grow modifiers

Checkbox (checkbox.g.css)

  • .checkbox — inline-flex label with hidden native input, styled box, animated checkmark
  • States: checked (scale-in animation), indeterminate, hover, focus-visible, disabled, error
  • Sizes: data-size="sm|md|lg" (default: md)
  • .checkbox-group — vertical by default; data-horizontal modifier for row layout

Radio (radio.g.css)

  • .radio — inline-flex label with hidden native input, styled circle, ::after dot
  • States: checked (dot scale-in), hover, focus-visible, disabled, error
  • Sizes: data-size="sm|md|lg" (default: md)
  • .radio-group — vertical by default; data-horizontal modifier for row layout

TypeScript Types

ts
InputSizes;    // ["sm", "md", "lg"]
InputStates;   // ["error", "success"]
CheckboxSizes; // ["sm", "md", "lg"]
RadioSizes;    // ["sm", "md", "lg"]

interface InputStyleProps {
  size?: InputSize;
  state?: InputState;
  disabled?: boolean;
}
interface InputWrapStyleProps {}
interface InputLeadingStyleProps {}
interface InputTrailingStyleProps {}
interface TextareaStyleProps {
  noResize?: boolean;
  autoGrow?: boolean;
}
interface CheckboxStyleProps {
  size?: CheckboxSize;
  state?: InputState;
  disabled?: boolean;
}
interface CheckboxGroupStyleProps {
  horizontal?: boolean;
}
interface RadioStyleProps {
  size?: RadioSize;
  state?: InputState;
  disabled?: boolean;
}
interface RadioGroupStyleProps {
  horizontal?: boolean;
}

Dist Structure

FileDescription
index.cssBarrel — imports all files below
input.cssToken definitions
input.g.cssGenerated text input + textarea styles
checkbox.g.cssGenerated checkbox styles
radio.g.cssGenerated radio styles
index.js / index.d.tsTypeScript types + runtime constants

Dependencies

Requires @vibe-labs/design-forms (sizing), @vibe-labs/design-components-core (field wrapper), and @vibe-labs/design (colors, surfaces, spacing, typography, transitions, elevation).

Build

bash
npm run build

Usage Guide

Import

css
@import "@vibe-labs/design-components-inputs";
ts
import type { InputStyleProps, CheckboxStyleProps, RadioStyleProps } from "@vibe-labs/design-components-inputs/types";

Variants

Input size

Set data-size on .input, .checkbox, .radio: sm · md (default) · lg

Validation state

Set data-state on .input, .checkbox, .radio: error · success

Textarea modifiers

  • data-no-resize on .textarea — disables resize handle
  • data-auto-grow on .textarea — auto-height grows with content

Checkbox / radio group orientation

  • data-horizontal on .checkbox-group or .radio-group — switches to row layout

Examples

Text input

html
<!-- Standard text input inside a field wrapper -->
<div class="field">
  <label class="field-label" for="name">Full name</label>
  <input id="name" type="text" class="input" placeholder="Jane Doe" />
</div>

Input with leading/trailing slots

html
<!-- Input with icon prefix and clear button suffix -->
<div class="field">
  <label class="field-label" for="search">Search</label>
  <div class="input-wrap">
    <span class="input-leading">
      <svg><!-- search icon --></svg>
    </span>
    <input id="search" type="search" class="input" placeholder="Search…" />
    <span class="input-trailing">
      <button class="close-btn" data-size="sm" aria-label="Clear">
        <svg><!-- × --></svg>
      </button>
    </span>
  </div>
</div>

Input validation states

html
<!-- Error state -->
<div class="field">
  <label class="field-label">Email</label>
  <input type="email" class="input" data-state="error" value="not-an-email" />
  <span class="field-error">Please enter a valid email address.</span>
</div>

<!-- Success state -->
<div class="field">
  <label class="field-label">Username</label>
  <input type="text" class="input" data-state="success" value="vibe_dev" />
  <span class="field-success">Username is available.</span>
</div>

Textarea

html
<div class="field">
  <label class="field-label">Description</label>
  <textarea class="textarea" data-no-resize placeholder="Enter a description…"></textarea>
</div>

Checkbox group

html
<!-- Vertical checkbox group (default) -->
<div class="field">
  <span class="field-label">Notifications</span>
  <div class="checkbox-group">
    <label class="checkbox">
      <input type="checkbox" checked />
      Email
    </label>
    <label class="checkbox">
      <input type="checkbox" />
      SMS
    </label>
    <label class="checkbox">
      <input type="checkbox" />
      Push
    </label>
  </div>
</div>

<!-- Horizontal checkbox group -->
<div class="checkbox-group" data-horizontal>
  <label class="checkbox">
    <input type="checkbox" />
    Option A
  </label>
  <label class="checkbox">
    <input type="checkbox" checked />
    Option B
  </label>
</div>

Radio group

html
<!-- Vertical radio group (default) -->
<div class="field">
  <span class="field-label">Plan</span>
  <div class="radio-group">
    <label class="radio">
      <input type="radio" name="plan" value="free" checked />
      Free
    </label>
    <label class="radio">
      <input type="radio" name="plan" value="pro" />
      Pro
    </label>
    <label class="radio">
      <input type="radio" name="plan" value="enterprise" />
      Enterprise
    </label>
  </div>
</div>

With Vue

Use @vibe-labs/design-vue-inputs for <SbInput>, <SbTextarea>, <SbCheckbox>, <SbCheckboxGroup>, <SbRadio>, and <SbRadioGroup> which handle v-model binding and map InputStyleProps to data attributes.

Vibe