@uxbertlabs/webkit
v1.0.4
Published
A modern React component library with Tailwind CSS v4 support, featuring pre-styled components, design tokens, and TypeScript support.
Maintainers
Readme
@uxbertlabs/webkit
A modern, lightweight React component library built with TypeScript and Tailwind CSS v4. Provides a comprehensive set of pre-styled, accessible components and design tokens for building beautiful user interfaces quickly.
Features
- Modern React Components: Built with React 19+ and TypeScript for type safety
- Tailwind CSS v4: Leverages the latest Tailwind CSS features and utilities
- Design Tokens: Comprehensive design system with colors, typography, spacing, and more
- Fully Typed: Complete TypeScript support with exported types
- Tree-shakeable: Optimized bundle size with ES modules
- Flexible: Highly customizable components with className support via
tailwind-merge - Accessible: Built with accessibility in mind
Installation
# Using pnpm (recommended)
pnpm add @uxbertlabs/webkit
# Using npm
npm install @uxbertlabs/webkit
# Using yarn
yarn add @uxbertlabs/webkitPeer Dependencies
Make sure you have the following peer dependencies installed:
pnpm add react react-dom tailwindcssSetup
1. Import styles
Import the library styles after you import tailwind.
@import "tailwindcss";
@import "@uxbertlabs/webkit/assets/webkit.css";2. Import components
Import components from the package:
import { Button, Typography } from "@uxbertlabs/webkit";Components
Button
A versatile button component with multiple variants, sizes, and states.
Props
variant: Button style variant (solid, outlined, ghost) with color optionssize: Button size (xs, sm, md, lg, xl)radius: Border radius (none, sm, md, lg, full)loading: Show loading spinnerdisabled: Disable buttonas: Polymorphic component (render as different element)
Variants
Solid: solid-primary, solid-secondary, solid-tertiary, solid-action, solid-error, solid-success, solid-white, solid-black, solid-transparent
Outlined: outlined-primary, outlined-secondary, outlined-tertiary, outlined-action, outlined-error, outlined-success, outlined-white, outlined-black, outlined-transparent
Ghost: ghost-primary, ghost-secondary, ghost-tertiary, ghost-action, ghost-error, ghost-success, ghost-white, ghost-black, ghost-transparent
Usage
import { Button } from "@uxbertlabs/webkit";
function App() {
return (
<div>
{/* Basic button */}
<Button>Click me</Button>
{/* Different variants */}
<Button variant="solid-primary">Primary</Button>
<Button variant="outlined-secondary">Secondary</Button>
<Button variant="ghost-action">Ghost</Button>
{/* Different sizes */}
<Button size="xs">Extra Small</Button>
<Button size="sm">Small</Button>
<Button size="md">Medium</Button>
<Button size="lg">Large</Button>
<Button size="xl">Extra Large</Button>
{/* With loading state */}
<Button loading>Loading...</Button>
{/* Disabled */}
<Button disabled>Disabled</Button>
{/* Custom radius */}
<Button radius="full">Rounded</Button>
{/* As a link */}
<Button as="a" href="/home">
Link Button
</Button>
{/* Custom className */}
<Button className="mt-4 w-full">Full Width</Button>
</div>
);
}Typography
A flexible typography component for consistent text styling across your application.
Props
variant: Typography variant (display, heading, body sizes)weight: Font weight (thin to black)leading: Line height (Tailwind leading classes)as: Polymorphic component (render as different element)
Variants
Display: text-display-L, text-display-M, text-display-S, text-display-XS
Headings: text-heading-XXL, text-heading-XL, text-heading-L, text-heading-M, text-heading-S, text-heading-XS, text-heading-XXS
Body: text-body-XL, text-body-L, text-body-M, text-body-S, text-body-XS, text-body-XXS
Font Weights
font-thin, font-extralight, font-light, font-normal, font-medium, font-semibold, font-bold, font-extrabold, font-black
Usage
import { Typography } from "@uxbertlabs/webkit";
function App() {
return (
<div>
{/* Display text */}
<Typography variant="text-display-L">Large Display</Typography>
{/* Headings */}
<Typography variant="text-heading-XL" as="h1">
Main Heading
</Typography>
<Typography variant="text-heading-M" as="h2">
Sub Heading
</Typography>
{/* Body text */}
<Typography variant="text-body-M">
This is regular body text with medium size.
</Typography>
{/* With custom weight */}
<Typography variant="text-body-L" weight="font-bold">
Bold body text
</Typography>
{/* With custom leading */}
<Typography variant="text-body-M" leading="leading-relaxed">
Text with relaxed line height
</Typography>
{/* Custom className */}
<Typography className="text-blue-500">Blue text</Typography>
</div>
);
}Spinner
A circular loading spinner component.
Props
width: Spinner width in pixels (default: 16)className: Custom CSS classes
Usage
import { Spinner } from "@uxbertlabs/webkit";
function App() {
return (
<div>
{/* Default spinner */}
<Spinner />
{/* Custom size */}
<Spinner width={32} />
{/* Custom styling */}
<Spinner className="text-blue-500" width={24} />
</div>
);
}Hooks
useIntersectionObserver
A React hook that tracks the intersection of a DOM element with its containing element or the viewport using the Intersection Observer API.
Options
root: The element used as viewport (default: null)rootMargin: Margin around the root (default: '0%')threshold: Visibility percentage to trigger callback (default: 0)freezeOnceVisible: Freeze state once element becomes visible (default: false)onChange: Callback when intersection state changesinitialIsIntersecting: Initial intersection state (default: false)
Usage
import { useIntersectionObserver } from "@uxbertlabs/webkit";
function LazyImage({ src, alt }) {
const [ref, isIntersecting] = useIntersectionObserver({
threshold: 0.5,
freezeOnceVisible: true,
});
return (
<div ref={ref}>
{isIntersecting ? <img src={src} alt={alt} /> : <div>Loading...</div>}
</div>
);
}
// With callback
function TrackedSection() {
const { ref, isIntersecting } = useIntersectionObserver({
onChange: (isIntersecting, entry) => {
console.log("Section visibility changed:", isIntersecting);
},
});
return (
<section ref={ref}>{isIntersecting ? "Visible" : "Not visible"}</section>
);
}Design System
Tailwind Styles
The library includes a comprehensive set of Tailwind CSS utilities and design tokens:
Included Styles
- Colors: Semantic color palette (primary, secondary, tertiary, action, error, success, etc.)
- Typography: Pre-defined text sizes and styles
- Spacing: Consistent spacing scale (XXS, XS, S, M, L, XL, XXL, XXXL)
- Buttons: Pre-styled button variants
- Radius: Border radius utilities
- Layout: Layout utilities and helpers
- Breakpoints: Responsive breakpoint system
- Custom Variants: Additional Tailwind variants and utilities
All styles are automatically imported when you import the library components.
Extending the design system
You can extend from the base design system in two ways
1. Reassigning values of existing design tokens
:root {
--color-primary-100: #d4ebefff;
--color-primary-200: #a8d7dfff;
--color-primary-300: #7ac4d0ff;
--color-primary-400: #46b0c0ff;
--color-primary-500: #009bb0ff;
--color-primary-600: #088296ff;
--color-primary-700: #10697aff;
--color-primary-800: #125767ff;
--color-primary-900: #053947ff;
--color-primary-1000: #022c37ff;
}2. By declaring new design tokens using tailwind's @theme
:root {
--color-primary-50: #f0fcfeff;
}
@theme {
--color-primary-50: var(--color-primary-50);
}TypeScript Support
All components and hooks come with full TypeScript definitions. Import types as needed:
import type {
ButtonVariant,
Size,
Radius,
Weights,
Variants,
} from "@uxbertlabs/webkit";
const variant: ButtonVariant = "solid-primary";
const size: Size = "md";
const weight: Weights = "font-bold";Customization
All components support the className prop for custom styling. The library uses tailwind-merge to intelligently merge class names:
import { Button, Typography } from "@uxbertlabs/webkit";
function App() {
return (
<>
{/* Override default styles */}
<Button className="bg-purple-500 hover:bg-purple-600">
Custom Button
</Button>
{/* Add additional styles */}
<Typography className="uppercase tracking-wide">Styled Text</Typography>
</>
);
}Polymorphic Components
Button and Typography components support the as prop for rendering as different HTML elements:
import { Button, Typography } from "@uxbertlabs/webkit";
function App() {
return (
<>
{/* Render button as a link */}
<Button as="a" href="/home" target="_blank">
Link
</Button>
{/* Render Typography as different headings */}
<Typography as="h1" variant="text-heading-XL">
H1 Heading
</Typography>
<Typography as="span" variant="text-body-S">
Span text
</Typography>
</>
);
}Development
We use pnpm as our package manager.
# Install dependencies
pnpm install
# Start development server
pnpm dev
# Build library
pnpm build:lib
# Run Storybook
pnpm storybook
# Build Storybook
pnpm build-storybook