npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@rufous/ui

v0.1.81

Published

Experimental: A lightweight React UI component library (Beta)

Downloads

1,398

Readme

Rufous UI

A polished React component library built with design tokens, TypeScript, and zero runtime dependencies beyond React. Every component supports the sx prop for scoped style overrides.

Live Showcase → ui.dev.rufous.com


Installation

npm install @rufous/ui
# or
yarn add @rufous/ui

Setup

Import the global styles once in your app entry:

import "@rufous/ui/style.css";

Wrap your app with the theme provider:

import { RufousThemeProvider } from "@rufous/ui";
import "@rufous/ui/style.css";

ReactDOM.createRoot(document.getElementById("root")!).render(
  <RufousThemeProvider>
    <App />
  </RufousThemeProvider>
);

Components

Buttons

import { StandardButton, AddButton, SubmitButton, CancelButton } from "@rufous/ui";

<StandardButton onClick={fn}>Standard</StandardButton>
<AddButton onClick={fn}>Add Item</AddButton>
<SubmitButton onClick={asyncFn}>Save</SubmitButton>
<CancelButton onClick={fn}>Cancel</CancelButton>

| Prop | Type | Default | Description | |------|------|---------|-------------| | onClick | () => void \| Promise<void> | — | Supports async; shows loader until resolved | | isLoading | boolean | false | External loading state control | | disabled | boolean | false | Disables the button | | sx | SxProp | — | Scoped style overrides |


TextField

import { TextField } from "@rufous/ui";

<TextField
  label="Email"
  value={email}
  onChange={(e) => setEmail(e.target.value)}
  variant="outlined"
  required
/>

| Prop | Type | Default | |------|------|---------| | label | string | — | | variant | 'outlined' \| 'filled' \| 'standard' | 'outlined' | | size | 'small' \| 'medium' | 'medium' | | color | 'primary' \| 'secondary' \| 'error' \| 'success' \| 'warning' \| 'info' | 'primary' | | error | boolean | false | | helperText | ReactNode | — | | fullWidth | boolean | false | | InputProps | { startAdornment?, endAdornment? } | — | | sx | SxProp | — |


Select

import { Select } from "@rufous/ui";

<Select
  options={[{ value: "us", label: "United States" }]}
  value={country}
  onChange={setCountry}
  label="Country"
/>

// Multiple selection
<Select options={options} value={selected} onChange={setSelected} multiple label="Tags" />

DateField / DateRangeField

import { DateField, DateRangeField } from "@rufous/ui";

<DateField label="Start Date" value={date} onChange={setDate} />

<DateRangeField
  label="Date Range"
  value={range}
  onChange={setRange}
/>

Autocomplete

import { Autocomplete } from "@rufous/ui";

<Autocomplete
  options={["React", "Vue", "Angular"]}
  value={val}
  onChange={setVal}
  label="Framework"
/>

Checkbox

import { Checkbox } from "@rufous/ui";

<Checkbox
  label="I agree to the terms"
  checked={checked}
  onChange={setChecked}
/>

Dialog

import { BaseDialog } from "@rufous/ui";

<BaseDialog
  open={open}
  title="Confirm Delete"
  onClose={onClose}
  onConfirm={onConfirm}
  showCancelButton
  fullWidth
>
  <p>Are you sure you want to delete this item?</p>
</BaseDialog>

| Prop | Type | Description | |------|------|-------------| | open | boolean | Controls visibility | | title | string | Dialog title | | onClose | () => void | Close handler | | onConfirm | () => void \| Promise<void> | Async confirm; shows loader | | showCancelButton | boolean | Show cancel button | | fullWidth | boolean | Full container width | | sx | SxProp | Scoped style overrides |


Slider

import { Slider } from "@rufous/ui";

<Slider label="Volume" value={vol} onChange={setVol} valueLabelDisplay="auto" />

// Range
<Slider label="Price" value={[20, 80]} onChange={setRange} range min={0} max={200} />

Switch

import { Switch } from "@rufous/ui";

<Switch checked={on} onChange={setOn} label="Enable notifications" />

RadioGroup

import { RadioGroup, Radio } from "@rufous/ui";

<RadioGroup label="Payment" options={options} value={val} onChange={setVal} />

// Composed
<RadioGroup value={val} onChange={setVal}>
  <Radio value="card" label="Credit Card" />
  <Radio value="paypal" label="PayPal" />
</RadioGroup>

Rating

import { Rating } from "@rufous/ui";

<Rating value={stars} onChange={setStars} />
<Rating value={4.5} precision={0.5} readOnly />

ToggleButton

import { ToggleButtonGroup, ToggleButton } from "@rufous/ui";

// Exclusive (radio)
<ToggleButtonGroup value={alignment} onChange={setAlignment} exclusive>
  <ToggleButton value="left">Left</ToggleButton>
  <ToggleButton value="center">Center</ToggleButton>
  <ToggleButton value="right">Right</ToggleButton>
</ToggleButtonGroup>

// Multi-select
<ToggleButtonGroup value={formats} onChange={setFormats}>
  <ToggleButton value="bold"><strong>B</strong></ToggleButton>
  <ToggleButton value="italic"><em>I</em></ToggleButton>
</ToggleButtonGroup>

Avatar

import { Avatar, AvatarGroup } from "@rufous/ui";

<Avatar src="/photo.jpg" alt="Alice Johnson" size="medium" />
<Avatar alt="Alice Johnson" color="#a41b06" />  // initials fallback

<AvatarGroup max={4}>
  <Avatar alt="Alice" />
  <Avatar alt="Bob" color="#1565c0" />
</AvatarGroup>

Chip

import { Chip } from "@rufous/ui";

<Chip label="React" color="primary" />
<Chip label="Remove me" color="error" onDelete={() => {}} />
<Chip label="Click me" color="default" variant="outlined" onClick={fn} />

Divider

import { Divider } from "@rufous/ui";

<Divider />
<Divider variant="middle" />
<Divider textAlign="center">OR</Divider>
<Divider orientation="vertical" flexItem />

List

import { List, ListItem, ListItemText, ListItemButton, ListItemIcon, ListSubheader } from "@rufous/ui";

<List subheader={<ListSubheader>Inbox</ListSubheader>}>
  <ListItemButton selected onClick={fn}>
    <ListItemIcon>📩</ListItemIcon>
    <ListItemText primary="Messages" secondary="3 unread" />
  </ListItemButton>
</List>

Typography

import { Typography } from "@rufous/ui";

<Typography variant="h1">Heading</Typography>
<Typography variant="body1" color="textSecondary">Paragraph text</Typography>
<Typography variant="caption" gutterBottom>Caption</Typography>

Skeleton

import { Skeleton } from "@rufous/ui";

<Skeleton variant="text" width={200} />
<Skeleton variant="circular" width={40} height={40} />
<Skeleton variant="rounded" width={300} height={120} animation="wave" />

Tooltip

import { Tooltip } from "@rufous/ui";

<Tooltip title="Delete this item" placement="top" arrow>
  <button>Delete</button>
</Tooltip>

Progress

import { CircularProgress, RufousLogoLoader } from "@rufous/ui";

<CircularProgress size={36} />
<RufousLogoLoader />

Box / Stack / Grid

import { Box, Stack, Grid } from "@rufous/ui";

// Box — generic flex/layout container
<Box display="flex" gap={16} padding={24}>...</Box>

// Stack — 1D flex layout
<Stack direction="row" spacing={2}>
  <div>A</div>
  <div>B</div>
</Stack>

// Grid — 12-column responsive grid
<Grid container spacing={3}>
  <Grid item xs={12} md={6}>Main</Grid>
  <Grid item xs={12} md={6}>Sidebar</Grid>
</Grid>

Paper / Card / Accordion

import { Paper, Card, CardContent, CardHeader, CardActions, Accordion, AccordionSummary, AccordionDetails } from "@rufous/ui";

<Paper elevation={3}>Content</Paper>

<Card>
  <CardHeader title="Title" subheader="Subtitle" />
  <CardContent>Body</CardContent>
  <CardActions><button>Action</button></CardActions>
</Card>

<Accordion>
  <AccordionSummary>FAQ Question</AccordionSummary>
  <AccordionDetails>Answer text here.</AccordionDetails>
</Accordion>

Tabs

import { Tabs, Tab } from "@rufous/ui";

<Tabs value={tab} onChange={setTab}>
  <Tab value="home" label="Home" />
  <Tab value="settings" label="Settings" />
</Tabs>

Breadcrumbs

import { Breadcrumbs } from "@rufous/ui";

<Breadcrumbs separator="›">
  <a href="/">Home</a>
  <a href="/products">Products</a>
  <span>Current</span>
</Breadcrumbs>

Stepper

import { Stepper, Step, StepLabel, StepContent } from "@rufous/ui";

<Stepper activeStep={activeStep}>
  {steps.map((label) => (
    <Step key={label}>
      <StepLabel>{label}</StepLabel>
    </Step>
  ))}
</Stepper>

Menu

import { Menu, MenuItem, MenuList, MenuDivider } from "@rufous/ui";

<Menu open={open} anchorEl={anchorRef.current} onClose={() => setOpen(false)}>
  <MenuList>
    <MenuItem icon="👤">Profile</MenuItem>
    <MenuItem icon="⚙️">Settings</MenuItem>
    <MenuDivider />
    <MenuItem icon="🚪">Sign Out</MenuItem>
  </MenuList>
</Menu>

Drawer

import { Drawer } from "@rufous/ui";

<Drawer open={open} onClose={() => setOpen(false)} anchor="right" width={320}>
  <div style={{ padding: 24 }}>Drawer content</div>
</Drawer>

Snackbar

import { Snackbar } from "@rufous/ui";

<Snackbar
  open={open}
  onClose={() => setOpen(false)}
  message="Changes saved successfully"
  severity="success"
  autoHideDuration={4000}
  anchorOrigin={{ vertical: "bottom", horizontal: "left" }}
/>

Link

import { Link } from "@rufous/ui";

<Link href="/docs" color="primary">Documentation</Link>
<Link component="button" color="primary" onClick={fn}>Trigger action</Link>

Popper / Popover

import { Popper, Popover } from "@rufous/ui";

// Popper — no backdrop, low-level
<Popper open={open} anchorEl={anchorRef.current} placement="bottom-start">
  <div>Custom dropdown content</div>
</Popper>

// Popover — backdrop, closes on outside click
<Popover open={open} anchorEl={anchorRef.current} onClose={() => setOpen(false)}>
  <div style={{ padding: 20 }}>Popover content</div>
</Popover>

Transitions

import { Fade, Slide, Grow, Collapse, Zoom } from "@rufous/ui";

<Fade in={show}><div>Fades in/out</div></Fade>
<Slide in={show} direction="up"><div>Slides in from bottom</div></Slide>
<Grow in={show}><div>Grows from center</div></Grow>
<Collapse in={show}><div>Collapses vertically</div></Collapse>
<Zoom in={show}><div>Zooms in/out</div></Zoom>

Icons

import { CopyIcon, EditIcon, TrashIcon, DownloadIcon } from "@rufous/ui";

<CopyIcon onClick={() => copy(text)} />
<EditIcon />
<TrashIcon />
<DownloadIcon />

The sx Prop

Every component accepts an sx prop for scoped, per-instance style overrides using nested CSS selectors. Values are injected as a scoped <style> tag — no inline style conflicts.

import { TextField } from "@rufous/ui";
import type { SxProp } from "@rufous/ui";

<TextField
  label="Search"
  sx={{
    borderRadius: "12px",
    "& .rf-text-field__input": { fontSize: "0.9rem" },
    "&:hover": { boxShadow: "0 0 0 3px rgba(164,27,6,0.15)" },
  }}
/>

License

MIT © Rufous UI