# 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

```bash
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.

```tsx
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:

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

### Hover States

Style props can include hover variants:

```tsx
<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.

```tsx
<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.

```tsx
<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.

```tsx
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.

```tsx
<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.

```tsx
// 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.

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

#### Select

Dropdown select component.

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

#### Suggest

Autocomplete component with search.

```tsx
<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.

```tsx
<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.

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

### Other Components

#### Button

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

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

#### Icon

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

#### Checkbox & Radio

```tsx
<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.

```tsx
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:

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

### Responsive Utilities

```tsx
// 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:

```tsx
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
