Skip to content

jaylarson/jaylabs-ui

Repository files navigation

JayLabs UI

A premium React component library with a Soft Metallic design system. 22 production-ready components with TypeScript support, accessible markup, and zero CSS-in-JS dependencies.

Built for speed. Designed to impress.


Why JayLabs UI?

  • 22 polished components — forms, layout, navigation, feedback, and domain-specific cards
  • Soft Metallic design system — gradient accents, 3D metallic effects, crisp lines, and rounded corners
  • TypeScript-first — full type definitions for every component and prop
  • Pure CSS — no runtime overhead from CSS-in-JS; just import one stylesheet
  • Accessible — ARIA attributes, keyboard navigation, focus-visible states
  • Tiny footprint — only clsx as a runtime dependency
  • Tree-shakeable — ESM and CJS builds with per-component imports
  • Design tokens included — CSS custom properties + TypeScript exports for colors, spacing, typography, shadows, and transitions

Quick Start

Install

npm install @jaylabs/ui

Import styles (once, in your app's entry point)

import '@jaylabs/ui/dist/index.css';

Use components

import { Button, Card, CardBody, Input } from '@jaylabs/ui';

function App() {
  return (
    <Card variant="gradient" hoverable>
      <CardBody>
        <Input label="Email" placeholder="you@example.com" fullWidth />
        <Button variant="gradient" fullWidth>
          Get Started
        </Button>
      </CardBody>
    </Card>
  );
}

Components

Form Controls

Component Description
Button 5 variants (primary, secondary, outline, ghost, gradient), 3 sizes, loading state, icon support
Input Text input with label, error/helper text, left/right icons, 3 sizes
Select Native dropdown with custom chevron, option groups, icon support
Textarea Multiline input with resize control, character limits
Checkbox Tri-state (checked, unchecked, indeterminate), custom checkmark
Radio / RadioGroup Radio buttons with group management, horizontal/vertical layout
Toggle Switch toggle with label, 3 sizes, accessible switch role
DatePicker Calendar dropdown with month navigation, min/max dates, today shortcut

Layout & Data Display

Component Description
Card 4 variants (default, elevated, outlined, gradient) + Header, Body, Footer sub-components
Tabs / TabPanel 3 styles (default, pills, underline), badges, disabled tabs, full-width
Avatar Image with fallback initials, online/offline/away/busy status indicator
Badge Status indicators with dot mode, 7 color variants
Tooltip 4 positions, configurable delay, hover/focus triggers

Navigation

Component Description
Navbar 4 variants (default, gradient, transparent, dark), sticky, brand/actions slots
Sidebar Collapsible with sections, item badges, 3 variants (default, dark, gradient)
Breadcrumbs Custom separators, icon support, 3 sizes

Feedback

Component Description
Alert 4 severity levels with default icons, dismissible
Modal 5 sizes including fullscreen, overlay/escape close, scroll lock

Domain-Specific Cards

Component Built for Features
TaskCard DopeDash XP rewards, priority levels, streak counter, completion toggle, tags
EnvelopeCard MightyMailer Envelope flap animation, 6 email statuses, expandable body, to/from/subject
InventoryCard OrganizedMe Item image, location/quantity, condition badge, favorite toggle
CallerCard CallerIQ Caller type icons, risk score bar, carrier/location, report count

Design Tokens

Every value in the system is available as both a CSS custom property and a TypeScript export.

Colors

/* CSS */
var(--color-primary-blue)     /* #5B8DEF */
var(--color-primary-gradient) /* #7B68EE */
var(--color-primary-purple)   /* #9B7EDE */
var(--color-primary-accent)   /* #B8A4E8 */
var(--color-primary-dark)     /* #1E293B */
var(--gradient-primary)       /* linear-gradient(135deg, #5B8DEF, #7B68EE, #9B7EDE) */
// TypeScript
import { colors } from '@jaylabs/ui';

colors.primary.blue    // '#5B8DEF'
colors.primary.purple  // '#9B7EDE'
colors.gray[200]       // '#E2E8F0'
colors.success          // '#10B981'
colors.error            // '#EF4444'

Spacing

Token CSS Variable Value
xs --spacing-xs 4px
sm --spacing-sm 8px
md --spacing-md 16px
lg --spacing-lg 24px
xl --spacing-xl 32px
2xl --spacing-2xl 48px

Typography

--font-primary: 'Avenir Next', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
--font-size-xs: 0.75rem;   /* 12px */
--font-size-sm: 0.875rem;  /* 14px */
--font-size-base: 1rem;    /* 16px */
--font-size-lg: 1.125rem;  /* 18px */
--font-size-xl: 1.25rem;   /* 20px */

Shadows

--shadow-sm: 0 1px 2px rgba(0,0,0,0.05);
--shadow-md: 0 4px 6px -1px rgba(0,0,0,0.1);
--shadow-lg: 0 10px 15px -3px rgba(0,0,0,0.1);
--shadow-metallic: 0 4px 6px rgba(91,141,239,0.2), 0 2px 4px rgba(123,104,238,0.15);

Component API Reference

Button

<Button
  variant="primary" | "secondary" | "outline" | "ghost" | "gradient"
  size="sm" | "md" | "lg"
  fullWidth={false}
  loading={false}
  leftIcon={<Icon />}
  rightIcon={<Icon />}
  disabled={false}
>
  Click me
</Button>

Input

<Input
  label="Email Address"
  placeholder="you@example.com"
  size="sm" | "md" | "lg"
  error="Invalid email"
  helperText="We'll never share your email"
  leftIcon={<MailIcon />}
  rightIcon={<CheckIcon />}
  fullWidth={false}
  isRequired={false}
/>

Select

<Select
  label="Country"
  placeholder="Choose a country"
  options={[
    { value: 'us', label: 'United States' },
    { value: 'ca', label: 'Canada' },
    { value: 'uk', label: 'United Kingdom' },
  ]}
  size="sm" | "md" | "lg"
  error="Required field"
  leftIcon={<GlobeIcon />}
  fullWidth={false}
/>

Textarea

<Textarea
  label="Message"
  placeholder="Write your message..."
  size="sm" | "md" | "lg"
  resize="none" | "vertical" | "horizontal" | "both"
  error="Too short"
  helperText="Minimum 20 characters"
  fullWidth={false}
  rows={4}
/>

Checkbox

<Checkbox
  label="I agree to the terms"
  size="sm" | "md" | "lg"
  checked={true}
  indeterminate={false}
  error="You must agree"
  helperText="Required"
/>

Radio / RadioGroup

<RadioGroup
  name="plan"
  label="Select a plan"
  value={selected}
  onChange={setSelected}
  orientation="vertical" | "horizontal"
>
  <Radio value="free" label="Free" />
  <Radio value="pro" label="Pro" />
  <Radio value="enterprise" label="Enterprise" />
</RadioGroup>

Toggle

<Toggle
  label="Dark mode"
  size="sm" | "md" | "lg"
  checked={isDark}
  onChange={handleToggle}
  helperText="Enable dark theme"
/>

DatePicker

<DatePicker
  label="Start Date"
  value={date}
  onChange={setDate}
  placeholder="MM/DD/YYYY"
  minDate={new Date('2024-01-01')}
  maxDate={new Date('2025-12-31')}
  size="sm" | "md" | "lg"
  fullWidth={false}
  error="Date is required"
/>

Card

<Card
  variant="default" | "elevated" | "outlined" | "gradient"
  padding="none" | "sm" | "md" | "lg"
  hoverable={false}
  isActive={false}
>
  <CardHeader>Title</CardHeader>
  <CardBody>Content goes here</CardBody>
  <CardFooter>Footer actions</CardFooter>
</Card>

Tabs

<Tabs
  items={[
    { id: 'tab1', label: 'Overview' },
    { id: 'tab2', label: 'Analytics', badge: 12 },
    { id: 'tab3', label: 'Settings', icon: <GearIcon /> },
    { id: 'tab4', label: 'Coming Soon', disabled: true },
  ]}
  activeTab={activeTab}
  onChange={setActiveTab}
  variant="default" | "pills" | "underline"
  size="sm" | "md" | "lg"
  fullWidth={false}
/>

<TabPanel tabId="tab1" activeTab={activeTab}>
  Overview content
</TabPanel>

Alert

<Alert
  variant="info" | "success" | "warning" | "error"
  title="Heads up!"
  dismissible={true}
  onDismiss={handleDismiss}
  icon={<CustomIcon />}  // optional, uses default per variant
>
  This is an important message.
</Alert>

Avatar

<Avatar
  src="/photo.jpg"
  name="Jane Doe"            // fallback: shows "JD"
  size="xs" | "sm" | "md" | "lg" | "xl"
  variant="circle" | "rounded"
  status="online" | "offline" | "away" | "busy"
/>

Badge

<Badge
  variant="default" | "primary" | "success" | "warning" | "error" | "info" | "gradient"
  size="sm" | "md" | "lg"
  dot={false}
>
  New
</Badge>

Modal

<Modal
  isOpen={isOpen}
  onClose={handleClose}
  title="Confirm Action"
  size="sm" | "md" | "lg" | "xl" | "full"
  closeOnOverlay={true}
  closeOnEscape={true}
  showCloseButton={true}
  footer={<Button onClick={handleClose}>Done</Button>}
>
  Modal content here.
</Modal>

Tooltip

<Tooltip
  content="This is a tooltip"
  position="top" | "bottom" | "left" | "right"
  delay={200}
>
  <Button>Hover me</Button>
</Tooltip>

Navbar

<Navbar
  variant="default" | "gradient" | "transparent" | "dark"
  sticky={true}
  brand={<span>MyApp</span>}
  actions={<Button size="sm">Sign In</Button>}
>
  <NavbarItem href="/" isActive>Home</NavbarItem>
  <NavbarItem href="/about" icon={<InfoIcon />}>About</NavbarItem>
  <NavbarItem href="/contact">Contact</NavbarItem>
</Navbar>

Sidebar

<Sidebar
  variant="default" | "dark" | "gradient"
  collapsed={false}
  width="260px"
  header={<Brand />}
  footer={<UserInfo />}
>
  <SidebarSection title="Main">
    <SidebarItem icon={<HomeIcon />} isActive>Dashboard</SidebarItem>
    <SidebarItem icon={<ChartIcon />} badge={5}>Analytics</SidebarItem>
    <SidebarItem icon={<SettingsIcon />}>Settings</SidebarItem>
  </SidebarSection>
</Sidebar>

Breadcrumbs

<Breadcrumbs
  items={[
    { label: 'Home', href: '/' },
    { label: 'Products', href: '/products' },
    { label: 'Widget Pro' },
  ]}
  size="sm" | "md" | "lg"
  separator={<ChevronIcon />}  // optional, default chevron provided
/>

EnvelopeCard

<EnvelopeCard
  from="Jay Larson"
  to="editor@nytimes.com"
  subject="Exclusive: New Product Launch"
  status="draft" | "queued" | "sent" | "opened" | "replied" | "bounced"
  date="Feb 19, 2026"
  isOpen={false}
  onToggle={handleToggle}
>
  <p>Email body content shown when expanded...</p>
</EnvelopeCard>

TaskCard

<TaskCard
  title="Complete quarterly report"
  description="Summarize Q4 metrics for the board meeting"
  priority="low" | "medium" | "high" | "urgent"
  xp={50}
  isComplete={false}
  dueDate="Feb 20"
  streak={7}
  tags={['work', 'reports']}
  onToggle={handleToggle}
/>

InventoryCard

<InventoryCard
  name="Mechanical Keyboard"
  category="Electronics"
  location="Home Office"
  quantity={1}
  image="/keyboard.jpg"
  condition="new" | "good" | "fair" | "poor"
  tags={['tech', 'input devices']}
  isFavorite={true}
  onFavoriteToggle={handleFavorite}
/>

CallerCard

<CallerCard
  phoneNumber="(555) 123-4567"
  callerName="Acme Corp"
  callerType="person" | "business" | "spam" | "unknown" | "scam"
  carrier="Verizon"
  location="New York, NY"
  riskScore={25}
  reportCount={3}
  lineType="mobile" | "landline" | "voip" | "toll-free"
/>

Browser Support

Browser Version
Chrome 88+
Firefox 85+
Safari 14+
Edge 88+

Requirements

Dependency Version
React ^18.0.0
React DOM ^18.0.0

Bundle Size

Output Size
CSS ~60 KB (uncompressed)
ESM JS ~48 KB (uncompressed)
CJS JS ~52 KB (uncompressed)
Runtime deps clsx only (~1 KB)

License

MIT License. See LICENSE for details.


Built by JayLabs | organized.tools

About

UI Kit for Organized Tools

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors