agentic-ui

Button

Pressable button with multiple variants and sizes. Composes @base-ui/react Button with focus management and disabled-while-loading.

Variants

Controls the visual shape — filled, tinted, outlined, or borderless.

import { Button } from "@brijbyte/agentic-ui/button";
import "@brijbyte/agentic-ui/button.css";

export default function VariantsDemo() {
  return (
    <>
      <Button variant="solid">Solid</Button>
      <Button variant="soft">Soft</Button>
      <Button variant="outline">Outline</Button>
      <Button variant="ghost">Ghost</Button>
    </>
  );
}

Tones

Controls the semantic color. Combine any tone with any variant.

import { Button } from "@brijbyte/agentic-ui/button";
import "@brijbyte/agentic-ui/button.css";

const TONES = ["primary", "secondary", "destructive", "success", "warning"] as const;

export default function TonesDemo() {
  return (
    <>
      {TONES.map((tone) => (
        <Button key={tone} variant="solid" tone={tone}>
          {tone.charAt(0).toUpperCase() + tone.slice(1)}
        </Button>
      ))}
    </>
  );
}

Variants × Tones

Every combination of variant and tone.

Primary
Secondary
Destructive
Success
Warning
Solid
Soft
Outline
Ghost
import { Fragment } from "react";
import { Button } from "@brijbyte/agentic-ui/button";
import type { ButtonVariant, ButtonTone } from "@brijbyte/agentic-ui/button";
import "@brijbyte/agentic-ui/button.css";

const VARIANTS: ButtonVariant[] = ["solid", "soft", "outline", "ghost"];
const TONES: ButtonTone[] = ["primary", "secondary", "destructive", "success", "warning"];

const label = (s: string) => s.charAt(0).toUpperCase() + s.slice(1);

const cellStyle: React.CSSProperties = {
  display: "flex",
  alignItems: "center",
  justifyContent: "center",
};

const headStyle: React.CSSProperties = {
  fontFamily: "var(--font-mono)",
  fontSize: "var(--font-size-xs)",
  color: "var(--color-tertiary)",
  textAlign: "center",
};

export default function MatrixDemo() {
  return (
    <div
      style={{
        display: "grid",
        gridTemplateColumns: `80px repeat(${TONES.length}, 1fr)`,
        gap: "var(--space-2)",
        alignItems: "center",
        width: "100%",
      }}
    >
      {/* Header row */}
      <div />
      {TONES.map((tone) => (
        <div key={tone} style={headStyle}>
          {label(tone)}
        </div>
      ))}

      {/* Variant rows */}
      {VARIANTS.map((variant) => (
        <Fragment key={variant}>
          <div style={{ ...headStyle, textAlign: "left" }}>{label(variant)}</div>
          {TONES.map((tone) => (
            <div key={tone} style={cellStyle}>
              <Button variant={variant} tone={tone} size="sm">
                {label(tone)}
              </Button>
            </div>
          ))}
        </Fragment>
      ))}
    </div>
  );
}

Sizes

import { Button } from "@brijbyte/agentic-ui/button";
import "@brijbyte/agentic-ui/button.css";

export default function SizesDemo() {
  return (
    <>
      <Button size="xs">Extra Small</Button>
      <Button size="sm">Small</Button>
      <Button size="md">Medium</Button>
      <Button size="lg">Large</Button>
    </>
  );
}

States

import { useState } from "react";
import { Button } from "@brijbyte/agentic-ui/button";
import "@brijbyte/agentic-ui/button.css";

export default function StatesDemo() {
  const [loading, setLoading] = useState(false);

  const trigger = () => {
    setLoading(true);
    setTimeout(() => setLoading(false), 2000);
  };

  return (
    <>
      <Button disabled>Disabled</Button>
      <Button variant="outline" disabled>
        Disabled outline
      </Button>
      <Button loading={loading} onClick={trigger}>
        Deploy
      </Button>
      <Button loading={loading} loadingText="Deploying…" onClick={trigger}>
        Deploy
      </Button>
    </>
  );
}

Using base-ui render prop

import { Button } from "@brijbyte/agentic-ui/button";
import "@brijbyte/agentic-ui/button.css";

export default function RenderPropDemo() {
  return (
    // Render as <a> while keeping button behaviour and focus management.
    // eslint-disable-next-line jsx-a11y/anchor-has-content
    <Button variant="soft" nativeButton={false} render={<a href="/components/button" />}>
      Anchor button
    </Button>
  );
}