npm package: @schematize/util-ui-components
Description: Schematize UI Components Library
Author: Benjamin Bytheway
Latest version: 0.6.3

# @schematize/util-ui-components

A collection of reusable UI components for the Schematize platform.  This package provides essential UI building blocks including tables, file dropzones, permission selectors, and utility functions for data handling.

## Components and exports

- **Table Component**: Full-featured data table with sorting, filtering, pagination, and resizable columns
- **Permissions Selector Tree**: Hierarchical permission selection with visual tree representation
- **File Dropzone**: Drag-and-drop file upload component with image preview and validation
- **Data URL Utilities**: Functions for reading files, resizing images, and converting to data URLs

## Dependencies

- `@schematize/refs`: Reference utilities for cross-platform compatibility
- `@schematize/instance.js`: Instance management and utilities
- `@schematize/ui.js`: Core UI framework and DOM manipulation
- `@schematize/util-common`: Common utility functions

## Installation

```bash
npm install @schematize/util-ui-components
```

## Usage

```javascript
import { 
  table, 
  fileDropzone, 
  permissionsSelectorTree
} from '@schematize/util-ui-components';
```

## API Reference

### table

Creates a full-featured data table component with sorting, filtering, pagination, and resizable columns.

#### Parameters

- `el` (Element): The DOM element to render the table into
- `attributes` (Object): HTML attributes to apply to the table element
- `callback` (Function): Optional callback function called after table creation
- `config` (Object): Configuration object containing:
  - `columns` (Array): Array of column definitions. Each column object can contain:
    - `title` (String): Column header text
    - `path` (Array): Property path array for data access (e.g., `['name']` or `['user', 'profile', 'firstName']`)
    - `type` (Function): Data type constructor for filtering (String, Number, Boolean, Date)
    - `width` (Number): Column width percentage (optional)
    - `cell` (Function): Custom cell renderer function that receives the cell element and returns DOM elements
    - `compareFn` (Function): Custom comparison function for sorting (optional)
  - `rows` (Function): An initializer function.  This is similar as to what you would call for `repeat` when using @schematize/ui.js.
  - `pageSize` (Number): Number of rows per page (default: 100)
  - `filter` (Object): Initial filter state
  - `sort` (Array): Initial sort configuration

#### Returns

- `Object`: The table DOM element

#### Usage

```javascript
const tableComponent = table(el, {
  className: 'table',
}, 0, {
  rows: (u) => (
    listen(_, ['items', [SYMBOL_ALL_PROPERTIES, 'change']], u, 1)
  ),
  columns: [{
    title: 'ID',
    path: ['__id__'],
    type: String,
    width: 30,
  }, {
    title: 'Name',
    path: ['name'],
    type: String,
  }],
});
```

#### Features

- **Sorting**: Click column headers to sort by that column
- **Filtering**: Built-in filter inputs for each column type
- **Pagination**: Automatic pagination with configurable page size
- **Resizable Columns**: Drag column borders to resize
- **Type-aware Filtering**: Different filter inputs based on column data type
- **Reactive Updates**: State changes automatically update the display

### fileDropzone

Creates a drag-and-drop file upload component with image preview and validation capabilities.

#### Parameters

- `el` (Element): The DOM element to render the dropzone into
- `attributes` (Object): HTML attributes to apply to the dropzone element
- `callback` (Function): Optional callback function called after dropzone creation
- `uploadCallback` (Function): Callback function called when files are uploaded
- `errorCallback` (Function): Callback function called when upload errors occur

#### Returns

- `Object`: The file dropzone DOM element

#### Usage

```javascript
fileDropzone(el, {}, (el, _ = el._) => (
  set(_, 'imageMaxWidth', 256),
  set(_, 'imageMaxHeight', 256)
), (data) => (
  set(_.item, 'avatar', imageToDataURL(data[0]))
), (err) => (
  _.showToast({
    m: err.message,
    t: 'error',
    d: 10000,
  })
))
```

#### Features

- **Drag and Drop**: Visual feedback for drag operations
- **File Validation**: Configurable file type acceptance
- **Image Preview**: Automatic preview for image files
- **Image Resizing**: Optional image resizing with max width/height
- **Base64 Encoding**: Automatic conversion to data URLs
- **Error Handling**: Comprehensive error reporting
- **Accessibility**: Full keyboard and screen reader support

### permissionsSelectorTree

Creates a hierarchical permission selection component with visual tree representation using SVG.

#### Parameters

- `el` (Element): The DOM element to render the tree into
- `attributes` (Object): HTML attributes to apply to the tree element
- `cb` (Function): Callback function called when permissions change
- `config` (Object): Configuration object containing:
  - `permissions` (Array): Array of permission objects with hierarchy
  - `selected` (Array): Initially selected permissions
  - `readonly` (Boolean): Whether the tree is read-only

#### Returns

- `Object`: The permissions selector tree DOM element

#### Usage

```javascript
permissionsSelectorTree(el, {}, (el, _ = el._) => (
  listen(_, ['mode'], () => (
    set(_, 'disabled', (_['mode'] !== 'edit'))
  ), 1),
  on(_, 'change', () => (
    asn(_['packageAccess'], {
      r: _.r,
      c: _.c,
      u: _.u,
      d: _.d,
    })
  )),
  listen(_, ['packageAccess', [SYMBOL_ALL_PROPERTIES, 'change']], (v) => (
    asn(_, {
      r: v.r,
      c: v.c,
      u: v.u,
      d: v.d,
    })
  ), 1)
), { r: 1, c: 1, u: 1, d: 1, a: 0 })
```

#### Features

- **Hierarchical Display**: Visual tree structure with SVG rendering
- **Checkbox Selection**: Three-state checkboxes (checked, unchecked, indeterminate)
- **Expandable Nodes**: Click to expand/collapse permission groups
- **Visual Indicators**: Diamond markers and connecting lines
- **Bulk Operations**: Select all/none functionality
- **State Persistence**: Maintains selection state across interactions

### readFileAsDataURL

Converts a File object to a data URL using the FileReader API.

#### Parameters

- `file` (File): The File object to convert

#### Returns

- `Promise<string>`: Promise that resolves to the data URL string

#### Usage

```javascript
const dataURL = await readFileAsDataURL(fileInput.files[0]);
console.log('Data URL:', dataURL);
```

#### Features

- **Promise-based**: Modern async/await support
- **Error Handling**: Automatic error propagation
- **File Type Support**: Works with any file type
- **Base64 Encoding**: Automatic base64 encoding for data URLs

### resizeDataURL

Resizes an image represented as a data URL to specified dimensions while maintaining aspect ratio.

#### Parameters

- `dataURL` (String): The data URL of the image to resize
- `width` (Number): Target width in pixels (optional, maintains aspect ratio if not provided)
- `height` (Number): Target height in pixels (optional, maintains aspect ratio if not provided)
- `type` (String): Output image type (e.g., 'image/jpeg', 'image/png')

#### Returns

- `Promise<string>`: Promise that resolves to the resized image data URL

#### Usage

```javascript
const resizedImage = await resizeDataURL(originalDataURL, 300, 200, 'image/jpeg');
console.log('Resized image:', resizedImage);
```

#### Features

- **Aspect Ratio Preservation**: Automatically maintains original aspect ratio
- **Canvas-based Resizing**: Uses HTML5 Canvas for high-quality resizing
- **Format Conversion**: Can convert between different image formats
- **Error Handling**: Graceful handling of invalid images
- **Cross-origin Support**: Handles cross-origin images with proper CORS settings

### getAsString

Converts an item with a `getAsString` method to a Promise-based data URL.

#### Parameters

- `item` (Object): Object with a `getAsString` method that accepts a callback

#### Returns

- `Promise<string>`: Promise that resolves to the data URL string

#### Usage

```javascript
const dataURL = await getAsString(someItem);
console.log('Converted to data URL:', dataURL);
```

#### Features

- **Promise Wrapper**: Converts callback-based APIs to Promise-based
- **Generic Interface**: Works with any object that has a `getAsString` method
- **Error Handling**: Automatic error propagation
- **Async/Await Support**: Modern JavaScript async patterns

## Build and Development

This package is built using ES modules and requires a modern JavaScript environment.  The components are designed to work with the Schematize UI framework and use reactive state management.

## License

MIT

## Author

Benjamin Bytheway