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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@jsway/jui

v3.0.6

Published

JUI is a minimalistic yet powerful React component library that provides everything needed to build modern web applications. It combines a utility-first styling approach (similar to Tailwind CSS) with fully typed, composable components.

Readme

JUI - Just User Interface

JUI is a minimalistic yet powerful React component library that provides everything needed to build modern web applications. It combines a utility-first styling approach (similar to Tailwind CSS) with fully typed, composable components.

Installation

npm install @jsway/jui

Core Concepts

Utility-First Styling with useBoxItem

JUI uses a prop-based styling system that transforms style props into CSS classes. This approach provides the flexibility of inline styles with the performance of CSS classes.

import { Box, Text } from '@jsway/jui';

// Style props are converted to optimized CSS classes
<Box padding="m" background="grey-1" radius="2">
  <Text size="l" weight="bold" color="accent-6">
    Hello World
  </Text>
</Box>;

Responsive Design

All style props support responsive modifiers:

// Different widths at different breakpoints
<Box width="100 50@md 33@lg">Responsive content</Box>

Hover States

Style props can include hover variants:

<Box background="grey-1 grey-2@hover" cursor="pointer">
  Hover me
</Box>

Color System

JUI provides a carefully designed color palette:

Base Colors

  • white, black, transparent

Color Scales (1-6)

  • Grey: grey-1 to grey-6 (1 is darkest, 6 is lightest)
  • Dark: dark-1 to dark-6 (1 is darkest, 6 is lightest)
  • Light: light-1 to light-6 (1 is lightest, 6 is darkest)
  • Accent: accent-1 to accent-6 (1 is darkest, 6 is lightest)

Semantic Colors

  • Green: green-1, green-2
  • Red: red-1, red-2

Components

Layout Components

Box

The fundamental layout component with flexbox and grid support.

<Box horizontal spacing="m" justify="between" alignItems="center">
  <Box>Left content</Box>
  <Box>Right content</Box>
</Box>

// Grid layout
<Box grid="columns" columns={3} spacing="m">
  <Box>Item 1</Box>
  <Box>Item 2</Box>
  <Box>Item 3</Box>
</Box>

Box Props:

Layout & Sizing:

  • flex - Flex grow value: '0', '1', '2', '3', '4' or width values
  • shrink - Flex shrink: '0', '1', '2', '3', '4'
  • width - Width values with breakpoint support
  • height - Height values
  • maxWidth - Max width: 's', 'm', 'l', 'xl'
  • maxHeight - Max height: 'xxs', 'xs', 's', 'm', 'l', 'auto'
  • aspect - Aspect ratio: '1-1', '1-2', '2-1', '3-4', '4-3', '16-9'

Spacing:

  • margin - Margin: '0', 'xs', 's', 'm', 'l', 'xl' (supports 1-4 values)
  • padding - Padding: same values as margin

Colors & Appearance:

  • color - Text color from color system
  • background - Background color from color system
  • opacity - Opacity: '100', '90', '80', '70', '60', '50', '40', '30', '20', '10', '0'

Visibility:

  • visible - Visibility control with breakpoint support
  • inline - Display inline

Borders & Styling:

  • border - Border width/style by sides or 'inset-1', 'inset-2', 'inset-3', 'inset-5'
  • borderColor - Border color by sides
  • radius - Border radius: '0', '1', '2', '3', 'round'
  • shadow - Box shadow: boolean, '1', '2', '3'

Positioning:

  • position - Various position values including sticky and absolute positions
  • zIndex - Z-index: '0' to '10'
  • overlay - Overlay positioning
  • align - Alignment: 'right', 'top', 'center', 'bottom'

Flexbox Layout:

  • horizontal, vertical - Layout direction
  • wrap - Flex wrap
  • spacing - Gap between children: 'xs', 's', 'm', 'l', 'xl'
  • justify - Justify content: 'space', 'start', 'center', 'end'
  • alignItems - Align items: 'start', 'end', 'center', 'baseline', 'stretch'

Grid Layout:

  • grid - Grid type: 'columns', 'template'
  • columns - Number of columns: 1, 2, 3, 4
  • gridRows, gridColumns - CSS grid template values

Container:

  • as - HTML element type
  • fixed - Fixed positioning
  • stretch - Stretch to fill container
  • overflow - Overflow: 'hidden', 'auto'
  • fullScreen - Full screen mode
  • separator - Separator line style
  • cursor - Cursor style: 'pointer', 'auto', 'move', 'grab', 'not-allowed'
  • hoverable - Add hover effect

Typography

Text

Flexible text component with semantic HTML support.

<Text h1 size="4xl" weight="bold">Main Heading</Text>
<Text size="l" color="grey-6">Subtitle text</Text>
<Text caps size="s" color="accent-4">SMALL CAPS LABEL</Text>
<Text monospace background="light-1" padding="xs s">code snippet</Text>

Text Props:

Typography:

  • size - Text size: 's', 'm', 'l', 'xl', 'xxl', '3xl', '4xl', '5xl'
  • weight - Font weight: 'normal', 'medium', 'bold'
  • leading - Line height: 's', 'm', 'l'

Semantic Elements:

  • h1 through h5 - Header levels
  • as - HTML element: 'p', 'span', 'strong', 'em', etc.
  • link - Style as link
  • href - Link URL

Text Styling:

  • caps - Uppercase text
  • monospace - Monospace font
  • underline - Underline text
  • small, large - Quick size modifiers
  • strong - Medium font weight
  • sup, sub - Superscript/subscript

Text Layout:

  • block - Block display
  • right, center - Text alignment
  • truncate - Truncate with ellipsis
  • lineClamp - Clamp lines: boolean, '2'-'8'
  • line - Single line display

Icons:

  • icon - Icon name
  • iconPosition - Icon position: 'before', 'after'

Plus all Box props for layout and styling

Data Display

List

Standard list with selection, keyboard navigation, and drag support.

const items = [
  { id: 1, name: 'Item 1' },
  { id: 2, name: 'Item 2' },
  { id: 3, name: 'Item 3' },
];

<List
  data={items}
  itemKey={(item) => item.id}
  itemContent={(item) => <Text>{item.name}</Text>}
  onAction={(item) => console.log('Selected:', item)}
/>;

List Props:

  • data - Array of items
  • itemKey - Function to get unique key
  • itemContent - Render function for items
  • itemProps - Props for item styling
  • selectable, multiselect - Selection modes
  • onAction, onSelect - Event handlers
  • keyboard - Enable keyboard navigation
  • draggable - Enable drag and drop

LazyList

Virtualized list for large datasets with excellent performance.

<LazyList
  data={largeDataset}
  itemHeight={40}
  height={400}
  itemKey={(item) => item.id}
  itemContent={(item) => <Text>{item.name}</Text>}
  onLoadMore={loadNextPage}
/>

LazyList Props:

  • All List props
  • itemHeight - Height of each item (for virtualization)
  • height - Container height
  • onLoadMore - Infinite scroll callback
  • threshold - Scroll threshold for loading more

Form Components

Field

Unified field component that handles various input types with validation and autocomplete.

// Text input with validation
<Field
  label="Email"
  type="text"
  value={email}
  onChange={setEmail}
  validators={[
    { required: true, message: 'Email is required' },
    { pattern: /^[^\s@]+@[^\s@]+\.[^\s@]+$/, message: 'Invalid email' }
  ]}
/>

// Numeric input
<Field
  label="Age"
  type="numeric"
  value={age}
  onChange={setAge}
  min={0}
  max={120}
/>

// Select field
<Field
  label="Country"
  type="select"
  value={country}
  onChange={setCountry}
  data={countries}
  itemKey={c => c.code}
  itemContent={c => c.name}
/>

// Autocomplete field
<Field
  label="Search Users"
  type="suggest"
  value={user}
  onChange={setUser}
  data={async (search) => await searchUsers(search)}
  itemKey={u => u.id}
  itemContent={u => u.name}
  debounce={300}
/>

Field Props:

  • label - Field label
  • type - 'text', 'numeric', 'date', 'select', 'suggest'
  • value, onChange - Controlled component props
  • validators - Array of validation rules
  • data - Options for select/suggest (can be async function)
  • prefix, suffix - Icons or content
  • debounce - Debounce delay for suggest
  • placeholder, hint - Helper text
  • yearRange - Year range for date picker (default: 5)
  • All BoxItem props for styling

TextInput

Basic text input component.

<TextInput
  value={text}
  onChange={setText}
  placeholder="Enter text..."
  prefix={<Icon name="search" />}
  clearable
/>

Select

Dropdown select component.

<Select
  value={selected}
  onChange={setSelected}
  data={options}
  itemKey={(opt) => opt.id}
  itemContent={(opt) => opt.label}
  placeholder="Choose an option"
/>

Suggest

Autocomplete component with search.

<Suggest
  value={selected}
  onChange={setSelected}
  data={async (search) => await searchAPI(search)}
  itemKey={(item) => item.id}
  itemContent={(item) => item.name}
  debounce={300}
  clearable
/>

DateInput

Date picker with calendar popup.

<DateInput
  value={date}
  onChange={setDate}
  locale="en-US"
  yearRange={10}
  placeholder="Select date"
/>

DateInput Props:

  • value - Date | string | null
  • onChange - (value: Date | null) => void
  • locale - Locale for formatting (string or locale object)
  • yearRange - Years to show before/after current year (default: 5)
  • toggle - Allow calendar toggle (default: false)
  • Dynamic positioning - Calendar opens above input when no space below
  • Inherits all TextInput props except 'onChange' and 'value'

Dropdown

Low-level dropdown component for custom implementations.

<Dropdown
  opener={<Button>Open Menu</Button>}
  content={
    <Box padding="s" background="white" shadow="2">
      <Text>Dropdown content</Text>
    </Box>
  }
/>

Other Components

Button

<Button primary size="m" onClick={handleClick}>
  Primary Button
</Button>

<Button variant="secondary" icon="add">
  With Icon
</Button>

Icon

<Icon name="settings" size="m" color="accent-4" />

Checkbox & Radio

<Checkbox value={checked} onChange={setChecked}>
  Accept terms
</Checkbox>

<Radio value={option} onChange={setOption} options={[
  { value: 'a', label: 'Option A' },
  { value: 'b', label: 'Option B' },
]} />

Theming

JUI supports multiple themes that can be switched dynamically.

import { Theme } from '@jsway/jui';

<Theme theme="ascii">
  <App />
</Theme>;

Available themes:

  • default - Modern, clean design
  • ascii - Terminal-style ASCII theme
  • rects - Rectangular, minimalist theme

Advanced Features

Width System

JUI provides a comprehensive width system:

  • Semantic: 'auto', 'fit', 'screen', 'xxs', 'xs', 's', 'm', 'l', 'xl', 'xxl'
  • Percentages: '0', '3', '5', '7', '10', '15', '20', '25', '30', '33', '35', '40', '50', '60', '70', '80', '90', '100'
  • Fixed: '1px', '5px', '10px', '1em', '2em', '3em', '5em'

Spacing System

  • Values: '0', 'xs', 's', 'm', 'l', 'xl'
  • Axis-based: "s m" for vertical/horizontal
  • Side-based: "s m l xl" for top/right/bottom/left

Custom Styling with BoxItem Props

Almost all components accept BoxItem props for custom styling:

<TextInput
  padding="m"
  background="accent-1"
  border="1 dark-6"
  radius="2"
  value={text}
  onChange={setText}
/>

Responsive Utilities

// Hide on mobile, show on desktop
<Box visible="false true@md">
  Desktop only content
</Box>

// Different spacing on different screen sizes
<Box padding="s m@md l@lg">
  Responsive padding
</Box>

TypeScript Support

JUI is built with TypeScript and provides full type safety:

interface User {
  id: string;
  name: string;
  email: string;
}

<List<User>
  data={users}
  itemKey={(user) => user.id}
  itemContent={(user) => <Text>{user.name}</Text>}
  onAction={(user) => console.log(user.email)}
/>;

License

MIT © Oleg V. Richards