For the complete documentation index, see llms.txt. Markdown variants are available by appending .md to documentation URLs. Homepage markdown is available at /llms.md/content.md. An agent skill is available at /.well-known/agent-skills/site-skill.md.

Input

The Input component from this design system, built on Base UI.

Installation

$ pnpm dlx shadcn@latest add @cobalt/input

Sizes

States

Error message

Set aria-invalid on the input and render a FieldError under it.

Options

  • size="sm" is 32px tall and size="xs" is 24px tall. A number still sets the native size attribute.
  • variant="ghost" removes the fill, padding, radius and rings, for inline editing inside another surface.

Source

import { Input as InputPrimitive } from "@base-ui/react/input";
import { cn } from "cn";
import * as React from "react";

function Input({
  className,
  type,
  size,
  variant = "default",
  ...props
}: Omit<React.ComponentProps<"input">, "size"> & {
  size?: "default" | "sm" | "xs" | number;
  /** `ghost` removes the fill, padding and rings, for inline editing. */
  variant?: "default" | "ghost";
}) {
  return (
    <InputPrimitive
      type={type}
      data-slot="input"
      data-size={typeof size === "string" ? size : "default"}
      data-variant={variant}
      size={typeof size === "number" ? size : undefined}
      className={cn(
        // cobalt-allow-focus-within -- text input
        "h-9 w-full min-w-0 rounded-[10px] border-0 bg-[var(--surface-strong,var(--muted))] px-3 py-2 text-base text-foreground ring-2 ring-transparent ring-inset outline-none transition-[background-color,box-shadow,color] duration-150 ease-[ease] motion-reduce:transition-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-[color:var(--foreground-subtle,var(--muted-foreground))] hover:not-focus:not-disabled:not-aria-invalid:ring-[var(--border-hover,var(--border))] focus:not-disabled:not-aria-invalid:ring-[var(--foreground-subtle,var(--ring))] focus:placeholder:text-foreground disabled:cursor-not-allowed disabled:bg-[var(--input-disabled-surface,var(--muted))] disabled:text-[color:var(--input-disabled-foreground,var(--muted-foreground))] disabled:placeholder:text-[color:var(--input-disabled-foreground,var(--muted-foreground))] aria-invalid:bg-[var(--input-invalid-surface,color-mix(in_srgb,var(--destructive)_15%,transparent))] aria-invalid:placeholder:text-[color:var(--input-invalid-placeholder,var(--destructive))] md:text-sm data-[size=sm]:h-8 data-[size=sm]:px-2.5 data-[size=xs]:h-6 data-[size=xs]:rounded-[8px] data-[size=xs]:p-1.5 data-[size=xs]:text-xs data-[size=xs]:md:text-xs",
        variant === "ghost" &&
          // 2px on the left so the caret is not cut in half at the box edge.
          // cobalt-allow-focus-within -- text input
          "rounded-none bg-transparent py-0 pr-0 pl-0.5 hover:not-focus:not-disabled:not-aria-invalid:ring-transparent focus:not-disabled:not-aria-invalid:ring-transparent disabled:bg-transparent focus:placeholder:text-[color:var(--foreground-subtle,var(--muted-foreground))] data-[size=sm]:pr-0 data-[size=sm]:pl-0.5 data-[size=xs]:rounded-none data-[size=xs]:py-0 data-[size=xs]:pr-0 data-[size=xs]:pl-0.5",
        className
      )}
      {...props}
    />
  );
}

export { Input };